哪个C99编译器(Clang vs. GCC)更接近const结构域的标准?

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在这里表现得不合规.