强枚举类型定义:Clang Bug 还是 C++11 标准不确定性?



对于这样的代码:

typedef enum FooEnum : int FooEnum;
enum FooEnum : int { A = 1, B };

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;

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

更新:正如向我解释的那样,第一个 typedef 用于 objc++ 兼容性, 在 C++ 代码编译和 objc++ 期间使用相同的标头。

这是一个clang bug,你不能在typedef说明符之后有一个不透明的枚举声明。

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

但这个不是合法的 C++:

typedef enum FooEnum : int FooEnum;

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

typedef enum FooEnum : int FooEnum;

上述行无效。我假设您正在尝试转发声明。请参考下面的示例。

enum class FooEnum;
int fooStar(FooEnum&);
enum class FooEnum : int {
A =1,
B
};
int foo(FooEnum fooEnum) {
return static_cast<int>(fooEnum);
}
int fooStar(FooEnum& fooEnum) {
return static_cast<int>(fooEnum);
}

相关内容

最新更新