带有clang-902.0.39.2的Apple LLVM 9.1.0,使用-std=c11接受:
Apple LLVM 9.1.0 with clang-902.0.39.2, using -std=c11, accepts:
typedef struct { int i; float f; } S; for (S s = { 0, 0 }; s.i < 25; ++s.i, s.f = i/10.f) …但拒绝:
for (struct { int i; float f; } s = { 0, 0 }; s.i < 25; ++s.i, s.f = s.i/10.f) …显示以下消息:
错误:在"for"循环中声明了非局部变量
error: declaration of non-local variable in 'for' loop
由于Clang违反了C标准中的某些约束,因此拒绝它是正确的吗?哪个条款和段落?还是Clang错误?
Is Clang correct to reject this, because it violates some constraint in the C standard? Which clause and paragraph? Or is it a Clang bug?
推荐答案C11:
6.8.5.3 for语句
6.8.5.3 The for statement
1语句
for ( clause-1 ; expression-2 ; expression-3 ) statement表现如下:表达式expression-2是控制表达式,它是 在每次执行循环主体之前进行评估.表达式expression-3是 每次执行循环主体后,将其评估为void表达式.如果第1条是 声明,它声明的任何标识符的范围是声明的其余部分和整个循环,包括其他两个表达式;它是在对控制表达式进行第一次评估之前按执行顺序达到的.如果子句1是表达式,则在对控制表达式进行第一次求值之前,它会被视为空表达式.158)
behaves as follows: The expression expression-2 is the controlling expression that is evaluated before each execution of the loop body. The expression expression-3 is evaluated as a void expression after each execution of the loop body. If clause-1 is a declaration, the scope of any identifiers it declares is the remainder of the declaration and the entire loop, including the other two expressions; it is reached in the order of execution before the first evaluation of the controlling expression. If clause-1 is an expression, it is evaluated as a void expression before the first evaluation of the controlling expression.158)
剩下的[2],只是谈到处理省略的子句/表达式...
Left out [2], just speaking of handling ommited clauses/expressions...
158)因此,第1节指定了循环的初始化,可能声明了一个或多个变量供循环使用;控制表达式expression-2指定在每次迭代之前进行的求值,以便继续执行循环,直到表达式比较等于0为止;而expression-3指定在每次迭代之后执行的操作(例如递增).
158) Thus, clause-1 specifies initialization for the loop, possibly declaring one or more variables for use in the loop; the controlling expression, expression-2, specifies an evaluation made before each iteration, such that execution of the loop continues until the expression compares equal to 0; and expression-3 specifies an operation (such as incrementing) that is performed after each iteration.
没有提及任何限制.第二个例子是一个有效的声明–而且我认为clang也不会抱怨以下内容:
Nothing mentioned about any restrictions. So as second example is a valid declaration – and I assume clang does not complain about the following either:
void f(void) { struct { int x, y; } point; // use point... }–那么第二个示例应该是有效的C代码,据我所知,clang拒绝是错误的.
– then the second example should be valid C code, so as far as I see, clang is wrong in rejecting.
更多推荐
在内部声明结构吗?
发布评论