use*_*124 2 c++ gcc clang compiler-warnings visual-studio-2013
Clang,GCC和Visual Studio 2013抱怨这段代码.
struct { };
Run Code Online (Sandbox Code Playgroud)
Clang with -Weverything:
警告:匿名结构是GNU扩展
[-Wgnu-anonymous-struct]
海湾合作委员会-Wall -Wextra -pedantic:
警告:ISO C++禁止匿名结构
[-Wpedantic]
Visual Studio 2013 /W4:
警告C4094:未标记的'struct'声明没有符号
一旦我添加变量声明,警告就会消失.
struct { } x;
Run Code Online (Sandbox Code Playgroud)
所有三个人都抱怨未使用的变量.
我假设这仍然是一个匿名结构和非法C++,并且编译器出于某种原因停止警告.但由于行为在三个独立的编译器中持续存在,我想知道添加变量声明是否会以某种方式改变程序的语义.
如果这是非法程序,-pedantic-errors则不会导致Clang或GCC导致编译错误.类似地,对于Visual Studio,/Za应该强制编译错误,但它不会.
如果向结构添加字段,则区别很明显.
struct A {
// Anonymous struct
struct {
int x;
};
};
struct B {
// Not an anonymous struct
struct {
int x;
} y;
};
Run Code Online (Sandbox Code Playgroud)
使用匿名结构,您可以通过编写访问该x字段.A aa.x
与命名的结构,你要访问x的B b由写作b.y.x.
匿名结构是C11标准的一部分,它们是各种编译器中常见的扩展,包括GCC和MSVC.由于它们在C++中是非标准的,因此启用迂腐警告将触发诊断.这正是迂腐警告旨在实现的目标.
结构声明也可以声明变量.结构的名称称为"标记".省略两者都会创建一个匿名结构.
(注意:这些示例是说明性的.它们不是完整或正确的代码段.)
// Structure tag is "A", declares a variable named "x".
struct A { int field; } x;
x.field = 7;
A y;
y.field = 8;
// Structure tag is "B", no variables declared.
struct B { int field; };
B x;
x.field = 10;
// Structure has no tag, declares a variable named "y".
struct { int field; } y;
y.field = 12;
// Structure has no tag and declares no variable...
// therefore, it is an "anonymous struct".
// The contents are accessible from "outside" the structure.
struct { int field; };
field = 10;
Run Code Online (Sandbox Code Playgroud)
在MSVC中,您还可以通过以下方式创建匿名结构,但这是非标准的(GCC支持此通道-fms-extensions):
struct A { int x };
struct B { struct A; int y; };
// B has two fields, x and y.
Run Code Online (Sandbox Code Playgroud)
"匿名结构"的定义在N1570§6.7.2.1第13段中给出,
类型说明符是没有标记的结构说明符的未命名成员称为匿名结构 ...