你不能在C++中转发声明枚举,但你可以在C中.
对于使用某些C++代码的C代码库,有没有办法在C中使用前向声明的枚举,当在C++中使用该头时(extern "C" {..}块内)不会导致错误?
例:
extern "C" {
enum MyEnum;
}
int main() { return 0; }
Run Code Online (Sandbox Code Playgroud)
GCC给出错误:
error: use of enum ‘MyEnum’ without previous declaration
enum MyEnum;
^~~~~~
Run Code Online (Sandbox Code Playgroud)
Clang也失败了:
error: ISO C++ forbids forward references to 'enum' types
enum MyEnum;
Run Code Online (Sandbox Code Playgroud)
为了给出一些上下文,这是一个主要是C代码库,其中一个小的C++模块碰巧包含C代码的头.我可以做一些破解让C++忽略枚举,但是想知道在这种情况下C++是否可以使用C头.
更新:已经注意到官方的C规范不支持这一点,但是它似乎是一些最广泛使用的编译器中的事实上的标准:GCC/CLANG/MSVC.
在C中向前声明枚举没有任何意义。C中的枚举仅引入整数枚举常量。他们没有介绍您要使用的任何类型。每个枚举类型都是未指定的整数类型,与所有其他整数类型兼容,因此根本没有类型安全性。
typedef enum e12 { ONE, TWO } e12;
typedef enum e34 { THREE, FOUR } e34;
int main () {
e12 one = ONE;
e34 three = THREE;
one = three;
three = ONE;
return one + three;
}
Run Code Online (Sandbox Code Playgroud)
此C程序可在-Wall -Wextra -Wpedantic上使用gcc干净地编译。(当然,不能作为C ++程序使用)。
因此,有用的便携式跨语言解决方案将是
#ifdef __cplusplus
enum MyEnum : int;
#else
typedef int MyEnum; // 'enum MyEnum' would give no improvement over this
#endif
Run Code Online (Sandbox Code Playgroud)
从 C++11 开始,您可以在 C++ 中前向声明枚举。它被称为“不透明声明”而不是“前向声明”,因为从技术上讲,它会产生一些不同的效果:枚举的大小在其不透明声明之后已知,而对于前向声明的类型,则不是案件。
\n\n但是,从日常角度来看,这是相同的想法:您可以声明枚举并在代码中进一步使用它。来自 cppreference:
\n\n\n\n\n\n
enum-key\xc2\xa0attr(optional)\xc2\xa0nested-name-specifier(optional)\xc2\xa0identifier\xc2\xa0enum-base(optional)\xc2\xa0;(2) (since C++11)\n2)\xc2\xa0不透明枚举声明:定义枚举类型,但不定义其枚举器:在此声明之后,该类型是完整类型并且其大小已知。\xc2\xa0注:一个\xc2\xa0显式专业化声明\xc2\xa0of类模板的作用域枚举成员是 \xc2\xa0嵌套名称说明符\xc2\xa0 出现在标识符\xc2\xa0 之前的唯一情况(C++14 起)
\n