"anonymous structs"标准吗?而且,真的,他们*是什么*?

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

本文关键字:他们 anonymous 是什么 真的 structs 标准 而且      更新时间:2023-10-16

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

Microsoft C扩展允许你声明一个结构变量在另一个结构中,不给它命名。这些嵌套结构被称为匿名结构。c++不允许匿名结构。

可以像访问匿名结构的成员一样访问它们

@K-ballo

我被告知这个特性并不一定等同于仅仅创建一个未命名的结构体,但是我看不出标准措辞上的区别。

c++ 11说:

[C++11: 9/1]: […]class-head省略class-head-name类说明符定义了未命名的类。

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

c++ 03缺乏这种明确的措辞,但同样表明类型定义中的identifier是可选的,并在9.4.2/53.5/4中引用了"未命名类"。

  • 所以MSDN是错的,这些东西都是完全标准的吗?
  • 或者在"未命名的结构/类"之间缺少一些微妙之处,并且当用作阻止它们被此c++ 03/c++ 11功能覆盖的成员时相同?
  • 我错过了"未命名结构"answers"匿名结构"之间的一些根本区别吗?在我看来,它们就像是同义词。

所有标准文本都提到创建一个"未命名结构体":

struct {
   int hi;
   int bye;
};

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

在标准方法中,它可以像这样实例化为成员:

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

但是"匿名结构"有微妙的不同—这是一个"未命名结构"和你在父对象中神奇地从中获得成员的事实的结合:

struct Foo {
   struct {
      int hi;
      int bye;
   }; // <--- no member name!
};
int main()
{
   Foo f;
   f.hi = 3;
}

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

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

与"匿名联合"的标准功能比较,它们做类似的事情:

struct Foo {
   union {
      int hi;
      int bye;
   }; // <--- no member name!
};
int main()
{
   Foo f;
   f.hi = 3;
}

似乎,尽管术语"未命名"指的是类型(即:"类"或"结构")本身,术语"匿名"指的是实际实例化的成员(使用"结构"的旧含义,更接近于"某种 structy类型的对象")。

微软称之为匿名结构的东西是不标准的。未命名结构体只是一个没有名称的普通结构体。除非你也定义了一个这种类型的对象,否则你就无能为力了:

struct {
    int i;
    double d;
} my_object;
my_object.d = 2.3;

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

union {
    int i;
    double d;
};
d = 2.3;

标准讨论匿名联合: [9.5]/5

形式为

的并集
union { member-specification } ;

称为匿名联合;它定义了未命名类型的未命名对象。匿名联合的成员规范只能定义非静态数据成员。[注意:嵌套类型和函数不能在匿名联合中声明。]匿名联合的成员名称应与声明匿名联合的范围内任何其他实体的名称不同。出于名称查找的目的,在匿名联合定义之后,匿名联合的成员被认为是在声明匿名联合的作用域中定义的。(例子:

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

这里a和p像普通(非成员)变量一样使用,但由于它们是联合成员,所以它们具有相同的地址。-end example]

Microsoft讨论的匿名结构unions的这个特性,但应用于structs。不只是一个未命名的定义,重要的是要注意,匿名联合/结构的成员被认为是在声明匿名联合/结构的作用域中定义的。

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

相关文章: