关于c ++:“匿名结构”标准吗?


Are “anonymous structs” standard? And, really, what *are* they?

MSDN认为C++中的匿名结构是非标准的:

A Microsoft C extension allows you to declare a structure variable
within another structure without giving it a name. These nested
structures are called anonymous structures. C++ does not allow
anonymous structures.

You can access the members of an anonymous structure as if they were
members in the containing structure.

@巴罗同意。

有人告诉我,这个特性不一定和创建一个未命名的结构相同,但我看不出在标准措辞方面有什么区别。

C++ 11表示:

[C++11: 9/1]: [..] A class-specifier whose class-head omits the class-head-name defines an unnamed class.

并为缺少名称的类型定义提供完整的语法结构。

C++ 03缺少这种明确的措辞,但是同样地,在类型定义中EDCOX1的0个是可选的,并且引用EDCOX1 1和EDCOX1 2中的"未命名类"。

  • 那么,msdn是不是错了,这些东西都是完全标准的?
  • 或者,在"未命名的结构/类"中,是否存在一些微妙之处,当它们用作阻止这些C++ 03/C++ 11功能覆盖的成员时,会有一些微妙之处呢?
  • "未命名结构"和"匿名结构"之间是否缺少一些基本区别?他们看起来像我的同义词。


所有标准文本均指创建"未命名结构":

1
2
3
4
struct {
   int hi;
   int bye;
};

只是一个友好的类型,没有可访问的名称。

以标准的方式,它可以被实例化为这样的成员:

1
2
3
4
5
6
7
8
9
10
11
12
struct Foo {
   struct {
      int hi;
      int bye;
   } bar;
};

int main()
{
   Foo f;
   f.bar.hi = 3;
}

但是"匿名结构"有着微妙的不同,它是"未命名结构"的组合,并且您可以在父对象中神奇地从中获取成员:

1
2
3
4
5
6
7
8
9
10
11
12
struct Foo {
   struct {
      int hi;
      int bye;
   }; // <--- no member name!
};

int main()
{
   Foo f;
   f.hi = 3;
}

与直觉&dagger;相反,这不仅创建了嵌套在Foo中的未命名结构,还自动为您提供一个"匿名成员",使成员可以在父对象中访问。

这是非标准的功能。GCC确实支持它,Visual C++也是如此。Windows API头在默认情况下使用此功能,但您可以通过在包含Windows头文件之前添加#define NONAMELESSUNION来指定不需要它。

与执行类似操作的"匿名联合"的标准功能相比:

1
2
3
4
5
6
7
8
9
10
11
12
struct Foo {
   union {
      int hi;
      int bye;
   }; // <--- no member name!
};

int main()
{
   Foo f;
   f.hi = 3;
}

&匕首;虽然术语"未命名"指的是类型(即"类"或"结构"),但术语"匿名"指的是实际的实例化成员(使用更旧的"结构"含义,更接近于"某个structy类型的对象")。这可能是你最初困惑的根源。


微软称之为匿名结构的东西不是标准的。未命名的结构只是一个没有名称的普通结构。除非您还定义了一个该类型的对象,否则一个对象不能做太多的工作:

1
2
3
4
5
6
struct {
    int i;
    double d;
} my_object;

my_object.d = 2.3;

匿名联合是标准的一部分,它们具有阅读微软对其匿名结构的描述所期望的行为:

1
2
3
4
5
6
union {
    int i;
    double d;
};

d = 2.3;


标准讨论匿名工会[9.5]/5

A union of the form

1
union { member-specification } ;

is called an anonymous union; it defines an unnamed object of unnamed type. The member-specification of an anonymous union shall only define non-static data members. [ Note: Nested types and functions cannot be declared within an anonymous union. —end note ] The names of the members of an anonymous union shall be distinct from the names of any other entity in the scope in which the anonymous union is declared. For the purpose of name lookup, after the anonymous union definition, the members of the anonymous union are considered to have been defined in the scope in which the anonymous union is declared. [ Example:

1
2
3
4
5
void f() {
    union { int a; const char* p; };
    a = 1;
    p ="Jennifer";
}

Here a and p are used like ordinary (nonmember) variables, but since they are union members they have the same address. —end example ]

微软所说的匿名结构就是针对unions的这个特性,但应用于structs。不仅是未命名的定义,重要的是要注意,匿名联合/结构的mebers被认为是在声明匿名联合/结构的范围内定义的。

据我所知,标准中没有未命名结构的这种行为。请注意,在引用的示例中,您如何能够实现其他情况下不可能实现的事情,例如共享堆栈中变量的存储,而匿名结构不会给表带来任何新的内容。