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/42224637/

相关文章:

c++ - 将 const std::pair<T, U>& 绑定(bind)到 std::pair<const T, U> 的值

c - 对 C 有用的 GCcflags是什么?

c - 如何使用 pthreads 访问本地存储

C - Fgets &Scanf 从文本文件中读取

gcc - 基于 MIPS 的 codesourcery 工具链的编译参数?

C 到内联汇编

mvvm - 绑定(bind)到 mvvm 中的常量值

c - Valgrind 未显示有关内存区域重叠的错误

c - 什么定义了类型的大小?

c++ - const B 和 const A* 不兼容,即使 B 是 A* 的别名