c - 哪个 C99 编译器(Clang 与 GCC)更接近 const 结构字段的标准?

标签 c gcc constants clang c99

我有这样的代码:

$ 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!");
    }
}

关于其正确性的 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:

哪个编译器是正确的?

最佳答案

C99 标准在 6.5.16:2 中说:

An assignment operator shall have a modifiable lvalue as its left operand.

在 6.3.2.1:1 中:

A modifiable lvalue is an lvalue that does not have array type, does not have an incomplete type, does not have a const-qualified type, and if it is a structure or union, does not have any member (including, recursively, any member or element of all contained aggregates or unions) with a const-qualified type.

因此 GCC 发出警告是正确的。

此外,条款 6.5.16:2 位于 C99 标准的“约束”部分,因此符合标准的编译器需要为违反该条款的程序发出诊断。它仍然是未定义的行为:在发出诊断后,编译器仍然可以做它想做的事。但必须有一个消息。因此,Clang 在这里以不符合规范的方式行事。

关于c - 哪个 C99 编译器(Clang 与 GCC)更接近 const 结构字段的标准?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18527984/

相关文章:

c++ - 在这种情况下, volatile 限定词重要吗?

c - 使用与文件 B 共享的元素(外键)访问文件 A 中的数据

c++ - 在 Win8 中使用 GCC、C::B 安装 Ogre3D

c - gcc 不会编译 SDL C 程序(对 SDL 函数的 undefined reference )

c - 结构大小问题,要求不需要的内存?

c# - 为什么 IsLiteral 对十进制返回 false?

c++ - switch-case 标签中的 C11 和常量表达式求值

c - 基于 C 中的 bool 函数对列表重新排序?

vba - "Type"中的 Const 变量 - 语句 vba

c - 枚举声明错误