在C中定义的C++中正向声明枚举

Forward declaring enum in C++ defined in C

本文关键字:声明 枚举 定义 C++      更新时间:2023-10-16

我搜索了转发声明,但没有找到任何方法来解决我的问题。现在是:

1)有一个C-头文件,可以说是一个大型多组件软件的导出接口,它包含一个枚举typedef

"export.h":

// This is in "C"!
typedef enum _VM_TYPE {...., ...., ...,} VM_TYPE;

2)C++中的代码的一部分使用该导出。

"cpp_code.cpp":

// This is in C++
#include "export.h"
#include "cpp_header.hpp"
{ .... using VM_TYPE values to do stuffs....}

"cpp_header.hpp":

// Need to somehow forward declear VM_TYPE here but how?
Struct VM_INFO {
....
VM_TYPE VType; //I need to add this enum to the struct
....
};

很明显,问题出在cpp_head.hpp中,因为它不知道枚举。

我尝试添加到cpp_header.hpp

typedef enum _VM_TYPE VM_TYPE;

它确实会起作用那么为什么这样做呢因为它有C风格的语法?!不管怎样,上级"管理层"告诉我不要那样做("这是C++,不是C")。

根据目前事物的联系方式,还有其他方法可以实现这一点吗?他们不想更改/添加包含文件;"enum类"仅限c++,对吗?仅将"enum VM_TYPE"添加到cpp_header.hpp将得到关于重新定义的错误。

知道吗?谢谢

在问题中描述的特定情况下,您根本不需要转发声明。在编译开始之前,#include的所有文件基本上都会被复制粘贴到一个翻译单元中,并且由于#include "export.h"之前是#include "cpp_header.hpp",所以它只会工作,因为当编译器看到struct VM_INFO的定义时,它已经看到了enum _VM_TYPE的定义,所以你没有问题。在"cpp_header.hpp"中包含"export.h"和按顺序在"cpp_code.cpp"中包含它们之间基本上没有区别,因为在预处理后,最终得到的代码基本上相同。因此,您在这里所要做的就是确保以正确的顺序获得包含。

如果您曾经想要#include "cpp_header.hpp"而不在需要访问struct VM_INFO成员的翻译单元中包含"export.h"(这样就不能将其作为不完整类型),那么"export.h"设计得很糟糕,您应该将可能需要的任何内容的定义单独分解为一个新的头。如果如评论所示,你绝对不能做到这一点,并且需要有一个次优设计,那么你的下一个最佳选择是有两个版本的"cpp_header.hpp",一个只是重复enum _VM_TYPE的定义,另一个不重复。#include是任何翻译单元的第一个版本,在任何翻译单元中你都会做而不是还有#include "export.h",而#include是任何翻译单位的第二个版本。显然,任何这种类型的代码重复都会在未来引发问题。

此外,以下划线和大写字母开头的名称总是保留在C中,所以你真的不应该使用它们。如果将来的C版本决定使用_VM_TYPE,那么您将不得不使用过时的C版本,或者中断所有这些代码。

枚举不能是前向声明,因为编译器需要知道枚举的大小。枚举器的底层是编译器特定的,但通常是int。你能把枚举强制转换为int吗?