C++ “匿名结构”是标准的吗?而且,真的,他们*是*什么?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14248044/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Are "anonymous structs" standard? And, really, what *are* they?
提问by Lightness Races in Orbit
MSDN reckonsthat anonymous structs are non-standard in C++:
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.
Microsoft C 扩展允许您在另一个结构中声明一个结构变量,而无需为其指定名称。这些嵌套结构称为匿名结构。C++ 不允许匿名结构。
您可以访问匿名结构的成员,就像它们是包含结构中的成员一样。
I'm told that this feature isn't necessarily the same as just creating an unnamed struct but I can't see a distinction in terms of standard wording.
有人告诉我,此功能不一定与仅创建未命名结构相同,但在标准措辞方面我看不出区别。
C++11 says:
C++11 说:
[C++11: 9/1]
: [..]A class-specifierwhose class-headomits the class-head-namedefines an unnamed class.
[C++11: 9/1]
: [..]一个类说明符,其类头省略了类头名定义了一个未命名的类。
and provides an entire grammatical construction for a type definition missing a name.
并为缺少名称的类型定义提供完整的语法结构。
C++03 lacks this explicit wording, but similarly indicates that the identifier
in a type definition is optional, and makes reference to "unnamed classes" in 9.4.2/5
and 3.5/4
.
C++03 缺少这种明确的措辞,但类似地表明identifier
类型定义中的 是可选的,并且在9.4.2/5
和 中引用了“未命名的类” 3.5/4
。
- So is MSDN wrong, and these things are all completely standard?
- Or is there some subtlety I'm missing between "unnamed structs/classes" and the same when used as members that prevents them from being covered by this C++03/C++11 functionality?
- Am I missing some fundamental difference between "unnamed struct" and "anonymous struct"? They look like synonyms to me.
- 那么MSDN是不是错了,这些东西都是完全标准的?
- 或者我在“未命名的结构/类”和用作成员时是否缺少一些微妙之处,以防止它们被这个 C++03/C++11 功能覆盖?
- 我是否遗漏了“未命名结构”和“匿名结构”之间的一些根本区别?它们对我来说就像同义词。
回答by Lightness Races in Orbit
All the standard text refers to creating an "unnamed struct":
所有标准文本都指的是创建一个“未命名的结构”:
struct {
int hi;
int bye;
};
Just a nice friendly type, with no accessible name.
只是一个很好的友好类型,没有可访问的名称。
In a standard way, it could be instantiated as a member like this:
以标准方式,它可以像这样实例化为成员:
struct Foo {
struct {
int hi;
int bye;
} bar;
};
int main()
{
Foo f;
f.bar.hi = 3;
}
But an "anonymous struct" is subtly different — it's the combination of an "unnamed struct" and the fact that you magically get members out of it in the parent object:
但是一个“匿名结构”是微妙的不同——它是一个“未命名结构”和你在父对象中神奇地从中获取成员的事实的组合:
struct Foo {
struct {
int hi;
int bye;
}; // <--- no member name!
};
int main()
{
Foo f;
f.hi = 3;
}
Converse to intuition†, this does not merely create an unnamed struct that's nested witin Foo
, but also automatically gives you an "anonymous member" of sorts which makes the members accessible within the parent object.
与直觉†相反,这不仅会创建一个嵌套的未命名结构 witin Foo
,而且还会自动为您提供一个“匿名成员”,使成员可以在父对象中访问。
It is this functionality that is non-standard. GCC doessupport it, and so does Visual C++. Windows API headers make use of this feature by default, but you can specify that you don't want it by adding #define NONAMELESSUNION
before including the Windows header files.
正是这个功能是非标准的。GCC确实支持它,Visual C++ 也是如此。Windows API 标头默认使用此功能,但您可以通过#define NONAMELESSUNION
在包含 Windows 标头文件之前添加来指定您不需要它。
Compare with the standardfunctionality of "anonymous unions" which do a similar thing:
与做类似事情的“匿名联合”的标准功能进行比较:
struct Foo {
union {
int hi;
int bye;
}; // <--- no member name!
};
int main()
{
Foo f;
f.hi = 3;
}
†It appears that, though the term "unnamed" refers to the type (i.e. "the class" or "the struct") itself, the term "anonymous" refers instead to the actual instantiated member (using an older meaning of "the struct" that's closer to "an object of some struct
y type"). This was likely the root of your initial confusion.
†看来,虽然术语“未命名”指的是类型(即“类”或“结构”)本身,但术语“匿名”指的是实际实例化的成员(使用“结构“这更接近于“某种struct
y 类型的对象”)。这可能是您最初困惑的根源。
回答by Pete Becker
The things that Microsoft calls anonymous structs are not standard. An unnamed struct is just an ordinary struct that doesn't have a name. There's not much you can do with one, unless you also define an object of that type:
微软称之为匿名结构的东西不是标准的。未命名结构只是一个没有名称的普通结构。除非您还定义了该类型的对象,否则您无能为力:
struct {
int i;
double d;
} my_object;
my_object.d = 2.3;
Anonymous unionsare part of the standard, and they have the behavior you'd expect from reading Microsoft's descriptionof their anonymous structs:
匿名联合是标准的一部分,它们具有您在阅读Microsoft对其匿名结构的描述时所期望的行为:
union {
int i;
double d;
};
d = 2.3;
回答by K-ballo
The standard talks about anonymous unions: [9.5]/5
关于匿名联合的标准:[9.5]/5
A union of the form
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:
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 ]
形式的联合
union { member-specification } ;
称为匿名联合;它定义了一个未命名类型的未命名对象。匿名联合的成员规范应仅定义非静态数据成员。[ 注意:嵌套类型和函数不能在匿名联合中声明。—尾注]匿名联合成员的名称应与声明匿名联合的范围内的任何其他实体的名称不同。出于名称查找的目的,在匿名联合定义之后,匿名联合的成员被认为已在声明匿名联合的范围内定义。[ 例子:
void f() { union { int a; const char* p; }; a = 1; p = "Jennifer"; }
这里 a 和 p 像普通(非成员)变量一样使用,但由于它们是联合成员,因此它们具有相同的地址。—结束示例]
The anonymous structsthat Microsofttalks about is this feature for unions
but applied to structs
. Is not just an unnamed definition, its important to note that mebers of the anonymous union/struct are considered to have been defined in the scope in which the anonymous union/struct is declared.
该匿名结构是微软谈论是此功能unions
,但应用到structs
。不仅仅是一个未命名的定义,重要的是要注意匿名联合/结构的成员被认为是在声明匿名联合/结构的范围内定义的。
As far as I know, there is no such behavior for unnamed structsin the Standard. Note how in the cited example you can achieve things that wouldn't be otherwise possible, like sharing storage for variables in the stack, while anonymous structsbring nothing new to the table.
据我所知,标准中的未命名结构没有这种行为。请注意,在引用的示例中,您如何实现原本不可能实现的功能,例如共享堆栈中变量的存储空间,而匿名结构不会为表带来任何新内容。