Why does following example not work in C?
#include <stdio.h>
typedef struct {
int x;
} X;
typedef struct {
char y[10];
} Y;
typedef struct {
int pos;
union {
X x;
Y y;
};
} Test;
int main() {
X x = { 65 };
Y y = { "Hallo" };
Test t = { 1, x }; // OK
printf("1: %d %d '%s'\n", t.pos, t.x.x, t.y.y);
Test t2 = { 2, y }; // ERROR
printf("2: %d %d '%s'\n", t2.pos, t2.x.x, t2.y.y);
Test t3 = { 3 }; // OK
printf("3: %d %d '%s'\n", t3.pos, t3.x.x, t3.y.y);
return 0;
}
main.c: In function ‘main’:
main.c:25:3: error: incompatible types when initializing type ‘int’ using type ‘Y’
Test t2 = { 2, y }; // ERROR
^
EDIT:
By the way: t2.y = y;
works
When initializing an object of struct or union type, the initializer must be a non-empty, (until C23) brace-enclosed, comma-separated list of initializers for the members: = { expression , ... }
Using designated initializers, a C99 feature which allows you to name members to be initialized, structure members can be initialized in any order, and any (single) member of a union can be initialized. Designated initializers are described in detail in Designated initializers for aggregate types (C only).
An anonymous union is a union without a name. It cannot be followed by a declarator. An anonymous union is not a type; it defines an unnamed object. The member names of an anonymous union must be distinct from other names within the scope in which the union is declared.
No! We cannot initialize a structure members with its declaration, consider the given code (that is incorrect and compiler generates error).
Because the initializer's type isn't analyzed and matched against the possible members of the union
.
Instead, you're simply supposed to provide an initializer for the first union
member.
C11 draft §6.7.9.17:
Each brace-enclosed initializer list has an associated current object. When no designations are present, subobjects of the current object are initialized in order according to the type of the current object: array elements in increasing subscript order, structure members in declaration order, and the first named member of a union.
As mentioned, you can use designators to control this:
Test t2 = { 2, .y = y };
should work (that .y
is a designator, "new" in C99).
You have to specify that you are initializing a member other than the first:
Test t2 = { 2, { .y = y } } ;
Otherwise the compiler will try to initialize it as if you wrote: .x = y
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With