Which C99-compiler (Clang vs. GCC) is closer to standard on const structure fields?

后端 未结 2 751
野的像风
野的像风 2020-12-11 18:55

I have code like this:

$ cat test.c 
#include 
typedef struct
{
    const int x;
} SX;

static SX mksx(void)
{
    return (SX) { .x = 10 };
}
         


        
相关标签:
2条回答
  • 2020-12-11 19:31

    The C99 standard says in 6.5.16:2:

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

    and in 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.

    So GCC is right to warn.

    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.

    0 讨论(0)
  • 2020-12-11 19:34

    const variable can't be modified after initialization, otherwise it's undefined behavior.

    Since it is undefined behavior, I think one can say both gcc and clang follow the standard. (Although gcc's choice seems better, it deserves a warning) (See EDIT below)

    The only way to give the variable x a value with defined behavior is to initialize it:

    SX sx = { .x = 10 };
    

    EDIT: As @Keith Thompson comments below, it's more than just undefined behavior in this case:

    C99 §6.5.16 Assignment operators

    Constraints

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

    This is a constraint, and according to:

    C99 §5.1.1.3 Diagnostics

    A conforming implementation shall produce at least one diagnostic message (identified in an implementation-defined manner) if a preprocessing translation unit or translation unit contains a violation of any syntax rule or constraint, even if the behavior is also explicitly specified as undefined or implementation-defined. Diagnostic messages need not be produced in other circumstances.

    A compiler must issue a diagnostic for any program that violates a constraint.

    Back to the question, gcc is correct is generate a warning, while clang fails to do so.

    0 讨论(0)
提交回复
热议问题