哪个 C99 编译器(Clang 与 GCC)更接近 const 结构字段的标准? [英] Which C99-compiler (Clang vs. GCC) is closer to standard on const structure fields?

查看:26
本文介绍了哪个 C99 编译器(Clang 与 GCC)更接近 const 结构字段的标准?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这样的代码:

$ 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个意见:

And 2 opinions about its correctness:

$ 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 中说:

The C99 standard says in 6.5.16:2:

赋值运算符应该有一个可修改的左值作为它的左操作数.

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

在 6.3.2.1:1 中:

and in 6.3.2.1:1:

可修改的左值是没有数组类型、没有不完整类型、没有 const 限定类型的左值,如果是结构体或联合体,则没有任何成员(包括,递归地,所有包含的聚合或联合的任何成员或元素)具有 const 限定类型.

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 发出警告是对的.

So GCC is right to warn.

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

In addition, the clause 6.5.16:2 is in a "Constraints" section of the C99 standard, so a conforming compiler is required to emit a diagnostic for a program that breaks the clause. It is still undefined behavior: the compiler can still do what it wants after the diagnostic is emitted. But there has to be a message. In consequence, Clang is behaving in a non-conforming manner here.

这篇关于哪个 C99 编译器(Clang 与 GCC)更接近 const 结构字段的标准?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆