为什么编译通过没有warnings/errors?
Why does the compilation pass with no warnings/errors?
#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 [=12=]x1,0x200456(%rip) # 6009dc <unionTry>
400583: 00 00 00
400586: c7 05 50 04 20 00 02 movl [=12=]x2,0x200450(%rip) # 6009e0 <unionTry+0x4>
40058d: 00 00 00
400590: c7 05 46 04 20 00 03 movl [=12=]x3,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 [=12=]x4006bc,%edi
4005b1: b8 00 00 00 00 mov [=12=]x0,%eax
4005b6: e8 e5 fe ff ff callq 4004a0 <printf@plt>
4005bb: b8 00 00 00 00 mov [=12=]x0,%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;
它不编译。
使用 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 版本。 Anonymous struct/union 是在 C11 中添加的(但在此之前作为 gcc 扩展存在)。
匿名结构和联合已在 C11 中标准化。 Gcc 之前允许它们作为扩展。对于这两个版本,结构或联合声明必须是明确的(此代码示例中的 a
是不明确的,因此违反了此规则)。在 C11 中,此类违规必须在编译时检测到,新版本的 Gcc 在使用 GNU 方言编译时也遵循此要求。
对于 Gcc 4.1.2,未检测到它。来自 docs [强调。我的]:
You must never create such structures that cause ambiguous field definitions. For example, this structure:
struct {
int a;
struct {
int a;
};
} foo;
It is ambiguous which a
is being referred to with foo.a
. Such constructs are not supported and must be avoided. In the future, such constructs may be detected and treated as compilation errors.
强调的条目已针对版本 4.6.4 进行了更改。
#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 [=12=]x1,0x200456(%rip) # 6009dc <unionTry>
400583: 00 00 00
400586: c7 05 50 04 20 00 02 movl [=12=]x2,0x200450(%rip) # 6009e0 <unionTry+0x4>
40058d: 00 00 00
400590: c7 05 46 04 20 00 03 movl [=12=]x3,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 [=12=]x4006bc,%edi
4005b1: b8 00 00 00 00 mov [=12=]x0,%eax
4005b6: e8 e5 fe ff ff callq 4004a0 <printf@plt>
4005bb: b8 00 00 00 00 mov [=12=]x0,%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;
它不编译。
使用 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 版本。 Anonymous struct/union 是在 C11 中添加的(但在此之前作为 gcc 扩展存在)。
匿名结构和联合已在 C11 中标准化。 Gcc 之前允许它们作为扩展。对于这两个版本,结构或联合声明必须是明确的(此代码示例中的 a
是不明确的,因此违反了此规则)。在 C11 中,此类违规必须在编译时检测到,新版本的 Gcc 在使用 GNU 方言编译时也遵循此要求。
对于 Gcc 4.1.2,未检测到它。来自 docs [强调。我的]:
You must never create such structures that cause ambiguous field definitions. For example, this structure:
struct { int a; struct { int a; }; } foo;
It is ambiguous which
a
is being referred to withfoo.a
. Such constructs are not supported and must be avoided. In the future, such constructs may be detected and treated as compilation errors.
强调的条目已针对版本 4.6.4 进行了更改。