M.B*_*rev 5 c gcc const c99 clang
我有这样的代码:
$ cat test.c
#include <stdio.h>
typedef struct
{
const int x;
} SX;
static SX mksx(void)
{
return (SX) { .x = 10 };
}
void fn(void)
{
SX sx;
while((sx = mksx()).x != 20)
{
printf("stupid code!");
}
}
Run Code Online (Sandbox Code Playgroud)
关于其正确性的2条意见:
$ for i in gcc clang; do echo "$i SAYS:"; $i -c -std=c99 -pedantic -Werror test.c; done
gcc SAYS:
test.c: In function ‘fn’:
test.c:15:2: error: assignment of read-only variable ‘sx’
while((sx = mksx()).x != 20)
^
clang SAYS:
Run Code Online (Sandbox Code Playgroud)
哪个编译器是对的?
Pas*_*uoq 12
C99标准在6.5.16:2中说:
赋值运算符应具有可修改的左值作为其左操作数.
在6.3.2.1:1中:
可修改的左值是一个左值,它没有数组类型,没有不完整的类型,没有const限定类型,如果是结构或联合,则没有任何成员(包括,递归地,任何成员)或具有const限定类型的所有包含聚合或联合的元素.
所以海湾合作委员会是正确的警告.
此外,条款6.5.16:2在C99标准的"约束"部分中,因此需要符合标准的编译器为违反该条款的程序发出诊断.它仍然是未定义的行为:在发出诊断之后,编译器仍然可以执行它想要的操作.但必须有一个信息.因此,Clang在这里表现得不合规.