Bug 71713

Summary: "initializer element is not constant" with nested casts
Product: gcc Reporter: vicencb
Component: cAssignee: Not yet assigned to anyone <unassigned>
Status: NEW ---    
Severity: enhancement CC: fw, msebor, yann
Priority: P3 Keywords: rejects-valid
Version: 6.1.1   
Target Milestone: ---   
Host: Target:
Build: Known to work:
Known to fail: Last reconfirmed: 2021-09-19 00:00:00

Description vicencb 2016-06-30 12:52:47 UTC
Hello,

With this type definitions:
 struct Str1 { int i; };
 struct Str2 { struct Str1 *m; };

Gcc fails to compile this:
 const struct Str2 cnt = { .m = (struct Str1[]){
  (struct Str1){1}
 }};
Reporting "error: initializer element is not constant"

If the inner cast is removed:
 const struct Str2 cnt = { .m = (struct Str1[]){
  {1}
 }};
Then it works fine.

As a side note, clang accepts it.

Thanks,
  Vicente.
Comment 1 Martin Sebor 2016-07-01 22:39:46 UTC
I believe the error is justified because a compound literal (i.e., "(struct Str1){1}") is not a constant expression, and so it cannot be used to initialize an object with static storage duration.  GCC accepts compound literals as initializers in some contexts as an extension but not here.  For instance, the following is accepted but in pedantic mode diagnosed with

  struct Str1 x = (struct Str1){ 0 };

  warning: initializer element is not constant [-Wpedantic]

...but it doesn't accept the more involved initializer in the submitted test case.  Since there are a number of enhancement requests to change GCC to accept more expressions as initializers that aren't constant expressions (for example, bug 53091) I will confirm this as such.
Comment 2 Yann Droneaud 2023-05-27 07:42:05 UTC
May be it's possible with GCC 13, with -std=gnu2x, and using C2x constexpr storage qualifier.