在以下代码中,编译/链接时没有错误或警告
enum E;
enum E;
int _tmain(int argc, _TCHAR* argv[]){ }
是VS2010的错误吗?
答案 0 :(得分:0)
你在这里做的是enum forward声明。一些编译器(如VS)提供了语言扩展,可以为C ++ 11之前的标准实现此行为。您可以通过在项目设置中禁用语言扩展来验证这一点,这将导致编译器错误。 G ++没有这样的扩展,但它应该在添加大小说明符后或使用enum class
时使用-std = c ++ 11编译代码。
在启用了编译器扩展的Visual Studio中有效
enum E;
enum E;
适用于所有支持C ++ 11的编译器
enum class E;
enum class E;
// or
enum E : short;
enum E : short;
答案 1 :(得分:0)
您的代码通过MS语言扩展编译VC ++ 2010及更高版本
您可以使用编译器标志/Za
禁用。
enum E;
enum E;
看起来就像enum E
的两个前向声明。在这种情况下,不会出现重复
相关。 N 某事物的前瞻性声明并不比一个人更合法或更不合法,因此效果如此
启用MS扩展程序(/Ze
)似乎包括启用转发enum
声明,
根据C ++ 03 或 C ++ 11,这是非法的。
但是这种外观具有误导性,如下面的程序所示:
#include <iostream>
enum E;
//enum E;
enum E e;
int main()
{
std::cout << (e == 0) << std::endl;
return e;
}
这也用VC ++ 2010或更高版本编译清理,证明了这一点
编译器解析enum E;
不是E
的前向声明,而是定义。
此处的语言扩展是enum E;
,一见钟情,等同于enum E {}
。
如果我们在程序中取消注释//enum E;
,它仍会编译干净,显示第二眼
然后,enum E;
不再再次解析为定义,就像重新声明E
一样。
VC ++ 2013支持作用域和的枚举的C ++ 11概念。禁用扩展程序, 它会编译并拒绝这段代码所示的声明:
enum UnscopedBasedEnum : int; // :)
enum UnscopedBasedEnum : int; // :)
UnscopedBasedEnum ube; // :)
enum struct ScopedBaselessEnum; // :)
enum struct ScopedBaselessEnum; // :)
ScopedBaselessEnum sbe;
//enum UnscopedBaseLessEnum; // :(
所有这些都符合C ++ 11。
ube
和sbe
的声明证明没有
这里的声明是一个前瞻声明,如果 foward声明具有习惯含义
不完整类型的声明。如果UnscopedBasedEnum
| ScopedBaselessEnum
在这些声明中是一个不完整的类型,那么ube
| sbe
的声明就会出现
会声明一个不完整类型的对象,并且不会编译。 Per C ++ 11,声明
UnscopedBasedEnum
和ScopedBaselessEnum
的不透明枚举声明,意思是
没有枚举列表存在或暗示。但他们仍宣布完整
类型: p 7.2.3
opaque-enum-declaration是对当前作用域中枚举的重新声明或声明 一个新的枚举。 [注意:opaque-enum-declaration声明的枚举具有固定的底层 类型并且是完整类型。枚举器列表可以在稍后的重新声明中使用枚举说明符提供。 - 后注]