强enum typedef:clang bug还是c ++ 11标准的不确定性?

use*_*932 10 c++ enums language-lawyer c++11

对于这样的代码:

typedef enum FooEnum : int FooEnum;
enum FooEnum : int { A = 1, B };
Run Code Online (Sandbox Code Playgroud)

clang(linux/7.0.0)报告没有错误[ -c -std=c++11 -pedantic],但gcc(linux/8.2.1)不编译它:

g++ -c -std=c++11 -pedantic test2.cpp
test2.cpp:1:28: error: expected ';' or '{' before 'FooEnum'
 typedef enum FooEnum : int FooEnum;
                            ^~~~~~~
test2.cpp:1:28: error: expected class-key before 'FooEnum'
test2.cpp:2:16: error: using typedef-name 'FooEnum' after 'enum'
 enum FooEnum : int { A = 1, B };
                ^~~
test2.cpp:1:28: note: 'FooEnum' has a previous declaration here
 typedef enum FooEnum : int FooEnum;
Run Code Online (Sandbox Code Playgroud)

事实上我不知道为什么在C++中使用typedef作为枚举,但问题是这是clang中的错误,因为它接受无效代码,或者这是c ++ 11标准中允许不同实现的错误?

更新:正如我所解释的那样,第一个typedef用于objc ++ compability,在c ++代码编译和objc ++中使用相同的头.

Oli*_*liv 8

这是一个clang bug,你不能在一个说明符之后有一个opaque-enum-declarationtypedef.

[dcl.typedef]/1

除了定义类型说明符之外,typedef说明符不应在decl-specifier-seq中与任何其他类型的说明符组合,[...]

[dcl.type]/1

限定型说明符:

  • 类型说明符

  • 类说明符

  • 枚举符

[dcl.enum]/1

枚举符:

  • enum-head {enumerator-listopt}

  • enum-head {enumerator-list,}

所以下面的代码是合法的c ++:

typedef enum FooEnum : int { A = 1, B } FooEnum;
Run Code Online (Sandbox Code Playgroud)

但这个不合法c ++:

typedef enum FooEnum : int FooEnum;
Run Code Online (Sandbox Code Playgroud)

因为enum FooEnum:int它不是定义类型说明符.