我有一个结构:
typedef struct _n
{
int type;
union {
char *s;
int i;
};
} n;
当我尝试分配复合文字时,例如:
node n1 = {1, 0};
node n2 = {2, "test"};
gcc给了我一些警告,例如:
warning: initialization makes pointer from integer without a cast
warning: initialization from incompatible pointer type
嗯,很明显,编译器不确定我只是为一个可能不明确的类型赋值。但是,即使我尝试更精确地指定:
node n0 = {type: 1, i: 4};
我明白了:
error: unknown field ‘i’ specified in initializer
我已经读过,如果我将(union <union name>)
放在i:
之前,那么它可能会有用。但是,我更喜欢拥有一个匿名联盟。有办法吗?
答案 0 :(得分:7)
匿名联合不是标准C - 它们是编译器扩展。我强烈建议给工会一个名字。如果你坚持使用匿名联合,那么你只能为它的第一个元素提供一个初始化器:
node n0 = {1, 0}; // initializes `s' to 0
当使用-Wall -Wextra -pedantic
编译时,gcc向我发出警告“在初始化程序周围缺少大括号”,这是一个有效的警告。实际上应该像这样指定初始化程序:
node n0 = {1, {0}}; // initializes `s' to 0
现在这只是警告“ISO C不支持未命名的结构/联合”。
如果您为联盟命名,那么您可以使用名为指定初始化程序的C99功能来初始化联合的特定成员:
typedef struct
{
int type;
union {
char *s;
int i;
} value;
} node;
node n0 = {1, { .s = "string"; }};
node n1 = {2, { .i = 123; }};
你需要工会才能有一个名字;否则,编译器会抱怨其中的指定初始化程序。
您尝试使用node n0 = {type: 1, i: 4}
的语法是无效的语法;看起来你试图使用指定的初始化器。