为什么C ++不允许使用匿名结构?

时间:2010-02-12 17:48:47

标签: c++ struct unions

某些C ++编译器允许匿名联合和结构作为标准C ++的扩展。这有点语法糖,偶尔会非常有用。

阻止此成为标准一部分的理由是什么?是否存在技术障碍?一个哲学的?或者仅仅是不足以证明它的合理性?

以下是我所谈论的一个示例:

struct vector3 {
  union {
    struct {
      float x;
      float y;
      float z;
    };
    float v[3];
  };
};

我的编译器会接受这个,但它会警告"nameless struct/union" is a non-standard extension to C++

6 个答案:

答案 0 :(得分:41)

正如其他人所指出的那样,标准C ++允许使用匿名联合,但匿名结构不允许。

原因是C支持匿名联合但不支持匿名结构*,因此C ++支持前者的兼容性而不支持后者,因为兼容性不需要它。

此外,C ++中的匿名结构没有多大用处。您演示的用法是,包含三个浮点数的结构可以由.v[i].x.y.z引用,我相信结果是未定义的C ++中的行为。 C ++不允许你写一个联盟的一个成员,比如说.v[1],然后从另一个成员那里读,比如说.y。尽管执行此操作的代码并不罕见,但实际上并未明确定义。

C ++用户定义类型的工具提供了替代解决方案。例如:

struct vector3 {
  float v[3];
  float &operator[] (int i) { return v[i]; }
  float &x() { return v[0]; }
  float &y() { return v[1]; }
  float &z() { return v[2]; }
};

* C11显然添加了匿名结构,因此未来的C ++修订版可能会添加它们。

答案 1 :(得分:17)

我会说,您只需使用vector3

即可清理union声明
union vector3 {
  struct { float x, y, z; } ;
  float v[3] ;
} ;

当然,anonymous structures was an MSVC extension。但ISO C11现在允许它,gcc allows it,Apple的llvm编译器也是如此。

为什么在C11而不是C ++ 11?我不确定,但实际上大多数(gcc ++,MSVC ++和Apple的C ++编译器)C ++编译器都支持它们。

答案 2 :(得分:7)

不确定你的意思。 C ++规范的第9.5节,第2节:

  

表格

的联合
union { member-specification } ;
     

被称为匿名联盟;它定义了一个未命名类型的未命名对象。

你也可以做这样的事情:

void foo()
{
  typedef
  struct { // unnamed, is that what you mean by anonymous?
    int a;
    char b;
  } MyStructType; // this is more of a "C" style, but valid C++ nonetheless

  struct { // an anonymous struct, not even typedef'd
    double x;
    double y;
  } point = { 1.0, 3.4 };
}

并不总是非常有用......虽然有时在令人讨厌的宏定义中很有用。

答案 3 :(得分:1)

工会可以是匿名的;见标准,9.5第2段。

您认为匿名结构或类的目的是什么?在推测为什么某些东西不在标准中之前,我想知道为什么它应该是,并且我没有看到用于匿名结构。

答案 4 :(得分:1)

您的代码

union {
  struct {
    float x;
    float y;
    float z;
  };
  float v[3];
};

就像

union Foo {
   int;
   float v[3];
};

肯定无效(在C99及之前)。

原因是可能来简化解析(在C中),因为在这种情况下你只需要检查struct / union主体是否只有“声明符语句”,如

Type field;

尽管如此,gcc and "other compilers"支持未命名的字段作为扩展名。

编辑:现在,C11(§6.7.2.1/ 13)正式支持匿名结构。

答案 5 :(得分:1)

基于编辑,评论和这篇MSDN文章:Anonymous Structures,我会冒险猜测 - 它与封装的概念很不一致。我不希望类的成员混淆我的类命名空间,而不仅仅是添加一个成员。此外,对匿名结构的更改可能会在未经许可的情况下影响我的课程。