"initializer element is not constant" using designated initializer on static struct with C99

StackOverflow https://stackoverflow.com/questions/20719966

  •  20-09-2022
  •  | 
  •  

Question

Can someone explain this behavior?

Using the compiler flag std=c99 I get the following errors:

  • "initializer element is not constant" for b1.
  • "expected expression before '.' token" for b2
  • b3 is OK.

When not using -std=c99 all lines are OK. When not using static b1 is ok. I'm using GCC.

typedef struct A_tag {
    int v;
    int w;
} A;

typedef struct B_tag {
    A super;
    int x;
    int y;
} B;

void test(){
static B b1 = ((B){.super={.v=100}, .x=10});
static B b2 = ({.super={.v=100}, .x=10});
static B b3 = {.super={.v=100}, .x=10};
}
Was it helpful?

Solution

(B){.super={.v=100}, .x=10} is not a "cast" but as a whole this is a "compound literal" a temporary object that only lives inside the corresponding expression (basically). Since this is not a constant but a temporary object, by the standard you can't initialize with it.

OTHER TIPS

As stated above, this is a "compound literal". Whether it can be used for initialization is actually implementation defined, IMO. The C11 standard says in [6.7.9 §4] that "expressions in an initializer for an object that has static or thread storage duration shall be constant expressions or string literals". Then in [6.6 §7] it lists what constant expressions can be and [6.6 §10] it allows an implementation to "accept other forms of constant expressions".

Since a "compound literals" is constant by definition, it ought to be possible to use it for initialization, although the standard does not explicitly say so. (And many compilers do accept it.)

Reading the C11 standard (actually N1570 which is a late draft), you will see that the rules for initializers of objects of static storage duration are different from the rules for those of automatic storage duration.

As I read it, compound literals can only be used for initializers of objects of automatic storage duration. They are allowed by 6.7.9 paragraph 13.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top