On 03/24/2015 03:26 PM, Alexey Neyman wrote:
Hi,
I am seeing a strange behavior when a compound initializer is used in a
structure initialization. A test case:
[[[
struct s {
int y;
unsigned long *x;
};
struct s foo = {
.y = 25,
.x = (unsigned long [SZ]){},
};
]]]
If SZ is zero, the initializer for .y (".y = 25") member is dropped as
well:
I'm having trouble finding support for any expectation in this
case. When SZ is zero, the source code above is invalid in C
not only because it attempts to create an array with zero
elements but also because it doesn't provide any initializers
for the initializer-list. Strictly speaking, it's required to
be diagnosed but at runtime it has undefined behavior.
It's unclear from the GCC manual (or from the apparent absence
of tests for this construct in the test suite) that the code
is intended to do something meaningful in GCC. The compiler
supports zero size arrays as an extension when declaring such
objects as the last members of structs. But in this case, the
code attempts to create an unnanmed temporary array of zero
elements which, IMO, makes no sense. At the same time, I
wouldn't expect gcc to simply omit the initialization for
foo.x. I suggest to open a gcc bug for it.
Martin
PS This is the output what I get with gcc 5.0:
$ cat u.c && gcc -Wall -Wextra -Wpedantic -std=c11 -ansi u.c && ./a.out
struct s {
int y;
unsigned long *x;
};
struct s foo = {
.y = 25,
.x = (unsigned long [0]){},
};
extern int printf (const char*, ...);
int main (void) {
printf ("%i %p\n", foo.y, (void*)foo.x);
return 0;
}
u.c:7:5: warning: ISO C90 forbids specifying subobject to initialize
[-Wpedantic]
.y = 25,
^
u.c:8:5: warning: ISO C90 forbids specifying subobject to initialize
[-Wpedantic]
.x = (unsigned long [0]){},
^
u.c:8:5: warning: ISO C forbids zero-size array [-Wpedantic]
u.c:8:29: warning: ISO C forbids empty initializer braces [-Wpedantic]
.x = (unsigned long [0]){},
^
u.c:8:29: warning: ISO C90 forbids compound literals [-Wpedantic]
u.c:9:1: warning: missing initializer for field ‘x’ of ‘struct s’
[-Wmissing-field-initializers]
};
^
u.c:3:20: note: ‘x’ declared here
unsigned long *x;
^
0 (nil)