c++gccaggregate-initialization

Why does this aggregate initialiser syntax compile on g++-9 but not g++-12?


Godbolt link: https://godbolt.org/z/rh84ahxb1

Code:

typedef struct {
    char letters[32];
} MyStruct;

int main() {
        MyStruct shortString = {{.letters=""}};
}

x86-64 gcc 12.2 returns this error:

<source>: In function 'int main()':
<source>:7:46: error: C99 designator 'letters' outside aggregate initializer
    7 |         MyStruct shortString = {{.letters=""}};
      |                                              ^
Compiler returned: 1

But the older gcc v9 does not throw any error, and happily compiles the file.

What caused the regression in behaviour from gcc 9 to gcc 12, and is there a way to force gcc 12 to match the behaviour of gcc 9, or will I need to downgrade to gcc 9 in order to compile the code without any changes?

I've found this bug report but I'm not sure how related it actually is. This recently caused a problem in CI/CD where updating the gcc caused previously-working code to break.


Solution

  • GCC 9 does not produce an error because it erroneously ignores the designator. For example, GCC 9 also accept the code if you change {{.letters=""}} to {{.frob=""}}, while GCC 12 correctly rejects it. (demo)

    I don't think there's a way to restore the incorrect behavior in GCC 12. You need to fix your code, e.g. by removing the spurious designator.