Clang,GCC和Visual Studio 2013抱怨这段代码。
struct { };
与-Weverything
:
警告:匿名结构是GNU扩展
[-Wgnu-anonymous-struct]
GCC与-Wall -Wextra -pedantic
:
警告:ISO C ++禁止匿名结构
[-Wpedantic]
带/W4
的Visual Studio 2013:
警告C4094:未标记的'结构'声明没有符号
一旦我添加变量声明,警告就会消失。
struct { } x;
所有三个人都抱怨未使用的变量。
我认为这仍然是一个匿名结构和非法C ++,并且编译器出于某种原因停止警告。但由于行为在三个独立的编译器中持续存在,我想知道添加变量声明是否会以某种方式改变程序的语义。
如果这是非法程序,-pedantic-errors
不会导致Clang或GCC导致编译错误。类似地,对于Visual Studio,/Za
应该强制编译错误,但它不会。
答案 0 :(得分:9)
如果向结构添加字段,则区别很明显。
struct A {
// Anonymous struct
struct {
int x;
};
};
struct B {
// Not an anonymous struct
struct {
int x;
} y;
};
使用匿名结构,您可以通过编写x
来访问A a
的{{1}}字段。
使用命名结构,您必须通过编写a.x
来访问x
B b
。
匿名结构是C11标准的一部分,它们是各种编译器中常见的扩展,包括GCC和MSVC。由于它们在C ++中是非标准的,因此启用迂腐警告将触发诊断。这正是迂腐警告的目的。
结构声明也可以声明变量。结构的名称称为“标记”。省略两者会创建一个匿名结构。
(注意:这些示例是说明性的。它们不是完整或正确的代码片段。)
b.y.x
在MSVC中,您还可以通过以下方式创建匿名结构,但这是非标准的(GCC通过// 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;
支持此功能):
-fms-extensions
“匿名结构”的定义见N1570§6.7.2.1第13段,
一个未命名的成员,其类型说明符是一个没有标记的结构说明符,称为匿名结构 ...
答案 1 :(得分:1)
struct { } x;
是一个unnamed
结构。
查看反义结构的示例:
struct phone
{
long number;
};
struct person
{
char name[30];
char gender;
struct phone; // Anonymous structure; no name needed
} Jim;