在C99中,对于迭代语句和选择语句,有新的块作用域,我理解if
,while
等本身也是块,因为它们的子语句也没有{ }
。
C11规范:
6.8.4:
选择语句是一个块,其范围是严格的子集 封闭区块的范围。每个相关的子语句也是一个 块的范围是选择范围的严格子集 言。
6.8.5
迭代语句是一个块,其范围是严格的子集 封闭区的范围。循环体也是一个块 scope是迭代语句范围的严格子集。
但如果我这样做:
if( (int a = 10) == 10 ) // error: expected expression before '==' token
int j = 10; // error: expected expression before 'int'
GCC给我错误。
如何验证C99新规则?
有人能给我一些有用的例子吗?
答案 0 :(得分:4)
C语言的语法根本不允许您尝试完成的任务。 N1570§6.8.4/ p1:
语法
选择语句:
if(表达)声明
表达式和语句都不被视为声明(声明表达式至最严格)。您可以做的最好的事情是将声明放在{}
括号内,例如:
int a = 10;
if (a == 10) {
int j = 10;
}
标准允许的唯一情况(并且确实由C99引入)是在for
循环中放置声明而不是初始化表达式:
for (int a = 0, b = 0; a + b < 20; a++, b++) {
int j = 10;
}
参考文献是§6.8.5/ p1(见表格):
语法
迭代语句:
而(表达)陈述
做声明而(表达);
for(表达式 opt ;表达式 opt ;表达式 opt )语句
for(声明表达式 opt ;表达式 opt )语句
这里真正的问题是if
语句的单独范围的目的是什么(截至§6.8.4/ p5),如果你不能将它与声明表达式一起使用。您看到只有for
循环才能实现。
答案 1 :(得分:1)
我读了一篇关于Straustrup的文章,他在那里讨论了C和C ++集成的问题。正如我们所看到的那样,似乎没有得到解决。甚至语句定义也有根本的不同。 在C中,if语句的控制表达式可能是表达式。例如,这句话
if ( const char *p = std::strchr( "Hello", 'H' ) ) { /*...*/ }
在C ++中有效,但类似的陈述
if ( char *p = strchr( "Hello", 'H' ) ) { /*...*/ }
在C中不是v。
但无论如何你的if语句既不是C ++中的vaid也不是C中的。:)
if( (int a = 10) == 10 )
可以有表达式或声明。来自C ++标准
condition:
expression
attribute-specifier-seqopt decl-specifier-seq declarator = initializer-clause
attribute-specifier-seqopt decl-specifier-seq declarator braced-init-list