Visual Studio 2010 unscoped opaque-enum-declaration,省略了基础

时间:2014-05-19 05:24:55

标签: c++ visual-c++ enums

在以下代码中,编译/链接时没有错误或警告

enum E;
enum E;
int _tmain(int argc, _TCHAR* argv[]){ }

是VS2010的错误吗?

2 个答案:

答案 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。

ubesbe的声明证明没有 这里的声明是一个前瞻声明,如果 foward声明具有习惯含义 不完整类型的声明。如果UnscopedBasedEnum | ScopedBaselessEnum 在这些声明中是一个不完整的类型,那么ube | sbe的声明就会出现 会声明一个不完整类型的对象,并且不会编译。 Per C ++ 11,声明 UnscopedBasedEnumScopedBaselessEnum不透明枚举声明,意思是 没有枚举列表存在或暗示。但他们仍宣布完整 类型: p 7.2.3

  

opaque-enum-declaration是对当前作用域中枚举的重新声明或声明   一个新的枚举。 [注意:opaque-enum-declaration声明的枚举具有固定的底层   类型并且是完整类型。枚举器列表可以在稍后的重新声明中使用枚举说明符提供。    - 后注]