#include <stdio.h>
union {
struct {
int a;
int c;
};
struct {
int b;
int a;
};
}unionTry;
int main(){
unionTry.a = 1;
unionTry.b = 2;
unionTry.c = 3;
printf("a = 0x%x b = 0x%x c = 0x%x\n", unionTry.a, unionTry.b, unionTry.c);
return 0;
}
反汇编:
400578: 55 push %rbp
400579: 48 89 e5 mov %rsp,%rbp
40057c: c7 05 56 04 20 00 01 movl $0x1,0x200456(%rip) # 6009dc <unionTry>
400583: 00 00 00
400586: c7 05 50 04 20 00 02 movl $0x2,0x200450(%rip) # 6009e0 <unionTry+0x4>
40058d: 00 00 00
400590: c7 05 46 04 20 00 03 movl $0x3,0x200446(%rip) # 6009e0 <unionTry+0x4>
400597: 00 00 00
40059a: 8b 0d 40 04 20 00 mov 0x200440(%rip),%ecx # 6009e0 <unionTry+0x4>
4005a0: 8b 15 3a 04 20 00 mov 0x20043a(%rip),%edx # 6009e0 <unionTry+0x4>
4005a6: 8b 35 30 04 20 00 mov 0x200430(%rip),%esi # 6009dc <unionTry>
4005ac: bf bc 06 40 00 mov $0x4006bc,%edi
4005b1: b8 00 00 00 00 mov $0x0,%eax
4005b6: e8 e5 fe ff ff callq 4004a0 <printf@plt>
4005bb: b8 00 00 00 00 mov $0x0,%eax
4005c0: c9 leaveq
4005c1: c3 retq
4005c2: 90 nop
输出:
$gcc -Wall a.c && ./a.out
a = 0x2 b = 0x2 c = 0x3
显然它缺乏C11标准支持。以下代码是否定义明确:
union {
struct {
int a;
int c;
};
struct {
int a;
int b;
};
}unionTry;
答案 0 :(得分:3)
匿名结构和工会已在C11中标准化。 Gcc之前允许他们作为扩展。对于这两个版本,结构或联合声明必须明确(在此代码示例中a
是不明确的,因此违反了此规则)。在C11中,必须在编译时检测到此类违规,并且在使用GNU方言进行编译时,新版本的Gcc也遵循此要求。
使用Gcc 4.1.2,它没有被检测到。来自docs [emph。矿]:
您绝不能创建导致模糊字段定义的结构。例如,这个结构:
struct { int a; struct { int a; }; } foo;
a
引用foo.a
是不明确的。不支持此类构造,必须避免使用。 将来,可能会检测到此类构造并将其视为编译错误。
版本4.6.4的强调条目已更改。
答案 1 :(得分:2)
它无法编译。
使用MinGW,gcc 4.9.1和您的编译器设置:
gcc -Wall test.c
test.c:9:13: error: duplicate member 'a'
int a;
^
使用适当的编译器设置:
gcc test.c -std=c11 -pedantic-errors -Wall -Wextra
test.c:9:13: error: duplicate member 'a'
int a;
^
更新您的gcc版本。在C11中添加了匿名结构/联合(但在此之前作为gcc扩展存在)。