``` struct foo {}; struct bar{ struct foo foo; }; static const struct foo my_foo = {}; static const struct bar my_bar = { .foo = my_foo, }; ``` Clang produces: ``` <source>:8:12: error: initializer element is not a compile-time constant .foo = my_foo, ^~~~~~ ``` GCC has no error. A recent CI run on the Linux kernel failed for Clang on this patch: https://cgit.freedesktop.org/~jani/drm/commit/?h=device-info-inheritance-v3&id=329fec687c7310f3a68ae1c6fd3638274484f149
If I change the `foo` member of `struct bar` from a `struct foo` to an `int`, then initialize `my_bar`'s `.foo` member with a `const int` Clang is happy. So it seems like a discontinuity that a `const struct` is not allowed. Both compilers error if the RHS of the initializer is not declared const. Also, changing the original defintion of `struct bar` to have a `const` qualified `struct foo` makes no difference.
Any use of a "const" variable in a global initializer is an extension in C. It's one of the few extensions that's actually allowed by the C standard, though. Probably makes sense to be compatible with gcc here.
Eli, can you help me find the relevant portion of the standard you're referring to? From the C11 draft, I'm looking at §6.6.7 and §6.7.9. Also, I'm having trouble finding any documentation of this feature on the GCC side. https://gcc.gnu.org/onlinedocs/gcc/C-Extensions.html I have this all working, just adding more tests for initializer lists vs designated initialization.
6.6 paragraph 10 says "An implementation may accept other forms of constant expressions". I'm not surprised it isn't documented in gcc; I think gcc implemented the extension by accident, and never formalized it later on. gcc accepts all sorts of weird stuff in global initializers (for example, "int x = x-3-x;").
Thanks Eli! https://reviews.llvm.org/D76096