61

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

Microsoft C 扩展允许您在另一个结构中声明结构变量而无需为其命名。这些嵌套结构称为匿名结构。C++ 不允许匿名结构。

您可以像访问包含结构中的成员一样访问匿名结构的成员。

@K-ballo同意

有人告诉我,此功能不一定与创建一个未命名的结构相同,但我看不出标准措辞方面的区别。

C++11 说:

[C++11: 9/1]: [..]省略类头名的类说明符定义了一个未命名的类。

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

C++03 缺少这种明确的措辞,但类似地表明identifier类型定义中的 是可选的,并引用了 和 中的“未命名类9.4.2/53.5/4

  • 那么MSDN错了吗,这些东西都是完全标准的?
  • 或者在“未命名的结构/类”和用作阻止它们被此 C++03/C++11 功能覆盖的成员时,我是否缺少一些微妙之处?
  • 我是否错过了“未命名结构”和“匿名结构”之间的一些根本区别?它们对我来说就像同义词。
4

3 回答 3

64

所有标准文本都是指创建一个“未命名的结构”:

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;
}

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

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

与做类似事情的“匿名联合”的标准功能进行比较:

struct Foo {
   union {
      int hi;
      int bye;
   }; // <--- no member name!
};

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

看起来,虽然术语“未命名”指的是类型(即“类”或“结构”)本身,但术语“匿名”指的是实际实例化的成员(使用“结构”的旧含义”这更接近于“某种structy 类型的对象”)。这可能是您最初困惑的根源。

于 2013-01-09T23:09:01.877 回答
14

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

struct {
    int i;
    double d;
} my_object;

my_object.d = 2.3;

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

union {
    int i;
    double d;
};

d = 2.3;
于 2013-01-09T23:07:17.870 回答
9

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

形式的联合

union { member-specification } ;

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

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

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

微软所说的匿名结构就是这个功能,但适用于. 不仅仅是一个未命名的定义,重要的是要注意匿名联合/结构的成员被认为已在声明匿名联合/结构的范围内定义。unionsstructs

据我所知,标准中的未命名结构没有这种行为。请注意,在引用的示例中,您如何实现原本不可能的事情,例如共享堆栈中变量的存储空间,而匿名结构不会带来任何新东西。

于 2013-01-09T23:09:41.020 回答