为什么C ++不允许匿名结构和联合?

一些C ++编译器允许匿名联合和结构作为标准C ++的扩展。 这是一些语法糖偶尔非常有帮助。

有什么理由阻止它成为标准的一部分? 有没有技术障碍? 一个哲学的? 还是只是不够的需要certificate它?

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

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

我的编译器会接受这个,但它警告说“无名结构/联合”是C ++的非标准扩展 。

正如其他人指出,匿名工会在标准C ++中是允许的,但匿名结构不是。

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

而且,C ++中的匿名结构没有多大用处。 你演示的用法,有一个包含三个浮动的结构,可以通过.v[i].x.y.z来引用,我相信在C ++中会导致未定义的行为。 C ++不允许你写联合的一个成员,例如.v[1] ,然后从另一个成员读取,比如.y 。 虽然这样做的代码并不罕见,但实际上并没有很好的定义。

C ++为用户定义的types提供了另外的解决scheme。 例如:

 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 ++版本可能会添加它们。

我会说,你可以通过使用union来清理你的vector3声明

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

当然, 匿名结构一个MSVC扩展 。 但ISO C11现在允许,而gcc允许 ,苹果的llvm编译器也是如此。

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

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

表单的联合

 union { member-specification } ; 

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

你也可以做这样的事情:

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

不总是非常有用…虽然有时用于讨厌的macros定义。

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

你有什么目的看到一个匿名结构或类履行? 在推测为什么标准中没有东西的时候,我想知道为什么应该这样做,而且我没有看到匿名结构的用法。

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

你的代码

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

就好像

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

这肯定是无效的(在C99和之前)。

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

 Type field; 

也就是说, gcc和“其他编译器”支持未命名的字段作为扩展名。

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