简体   繁体   English

为什么编译没有警告/错误?

[英]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;
}

The disassembly: 拆卸:

  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

The output: 输出:

$gcc -Wall a.c && ./a.out
a = 0x2 b = 0x2 c = 0x3

Apparently it is a lack of C11 standard support. 显然它缺乏C11标准支持。 Is the following code is well defined: 以下代码是否定义良好:

union {
    struct {
        int a;
        int c;
    };
    struct {
        int a;
        int b;
    };
}unionTry;

Anonymous structures and unions have been standardized in C11. 匿名结构和工会已在C11中标准化。 Gcc allowed them before as an extension. Gcc之前允许他们作为扩展。 For both versions, the structure or union declaration must be unambiguous ( a in this code example is ambiguous and thus violates this rule). 对于这两种型式中,结构或联合声明必须是明确的( a在该代码示例是不明确的,因此违反本规则)。 In C11, such violations must be detected at compile time, and new versions of Gcc follow this requirement also when compiling with a GNU dialect. 在C11中,必须在编译时检测此类违规,并且在使用GNU方言编译时,新版本的Gcc也遵循此要求。

With Gcc 4.1.2, it isn't detected. 使用Gcc 4.1.2时,未检测到它。 From the docs [emph. 来自文档 [emph。 mine]: 矿]:

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 . foo.a引用a是不foo.a Such constructs are not supported and must be avoided. 不支持此类构造,必须避免使用。 In the future, such constructs may be detected and treated as compilation errors . 将来,可以检测这些结构并将其视为编译错误

The emphasized entry has been changed for version 4.6.4 . 版本4.6.4更改了重点条目。

It does not compile. 它不编译。

With MinGW, gcc 4.9.1 and your compiler settings: 使用MinGW,gcc 4.9.1和您的编译器设置:

gcc -Wall test.c
test.c:9:13: error: duplicate member 'a'
         int a;
             ^

With proper compiler settings: 使用适当的编译设置:

gcc test.c -std=c11 -pedantic-errors -Wall -Wextra
test.c:9:13: error: duplicate member 'a'
         int a;
             ^

Update your version of gcc. 更新您的gcc版本。 Anonymous struct/union was added in C11 (but existed as a gcc extension before that). 在C11中添加了匿名结构/联合(但在此之前存在为gcc扩展名)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM