转发声明C++代码中使用的C头中的枚举?

ide*_*n42 5 c c++

你不能在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.

n. *_* m. 6

在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)

  • 使用枚举而非整数有一些优势-在GCC / Clang中,存在枚举感知警告(`-Wenum-compare`,`-Wswitch-enum`),地址清理器具有`-fsanitize = enum'-尽管不能保证,它们可以用来发现使用常规int不会检测到的代码中的实际错误。 (2认同)

Vas*_*kin 5

从 C++11 开始,您可以在 C++ 中前向声明枚举。它被称为“不透明声明”而不是“前向声明”,因为从技术上讲,它会产生一些不同的效果:枚举的大小在其不透明声明之后已知,而对于前向声明的类型,则不是案件。

\n\n

但是,从日常角度来看,这是相同的想法:您可以声明枚举并在代码中进一步使用它。来自 cppreference

\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)\n

\n\n

2)\xc2\xa0不透明枚举声明:定义枚举类型,但不定义其枚举器:在此声明之后,该类型是完整类型并且其大小已知。\xc2\xa0注:一个\xc2\xa0显式专业化声明\xc2\xa0of类模板的作用域枚举成员是 \xc2\xa0嵌套名称说明符\xc2\xa0 出现在标识符\xc2\xa0 之前的唯一情况(C++14 起)

\n
\n