是struct {} x; 一个匿名结构?

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应该强制编译错误,但它不会.

Die*_*Epp 9

如果向结构添加字段,则区别很明显.

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段中给出,

类型说明符是没有标记的结构说明符的未命名成员称为匿名结构 ...

  • @ user4393124`struct {} x`没有错. (2认同)