C++保留符号作为C变量名

C++ reserved symbol as C variable name

本文关键字:变量名 保留 符号 C++      更新时间:2023-10-16

我在C++项目中使用外部C库。

标头包含一个具有名为class:的变量的结构

#ifdef __cplusplus
extern "C" {
#endif
struct something_t {
...
sometype class;
};

#ifdef __cplusplus
}
#endif

g++不喜欢这样,并抱怨"错误:在';'标记之前需要标识符"。

我有什么选择?

  1. 我可以重命名class,但这很麻烦,破坏了上游兼容性
  2. 我可以要求上游项目重命名变量,但这可能很困难
  3. 我可以使用预处理器在标题中重新定义class#define class class_有任何副作用吗
  4. 还有其他建议吗

处理这种情况的最佳方法是什么

结果:基于对选项2的普遍偏好,我最终选择在上游库中启动重命名。

正如其他人在评论中提到的那样,最好的选择是围绕这个东西编写另一个C API层,该层只在内部使用另一个API。

与这个有问题的struct定义相关的任何内容都应该仅通过不透明指针导出。

在C++中,您可以使用清理过的C-API。


这是一个小草图:

ThirdParty.h(包含要用c++编译的有问题的代码)

#ifdef __cplusplus
extern "C" {
#endif
struct something_t {
...
sometype class;
};
struct something_t* CreateSomething(); // Does memory allocation and initialization
void DoSomething(struct something_t* something);
#ifdef __cplusplus
}
#endif

MyApiWrapper.h

#ifdef __cplusplus
extern "C" {
#endif
typedef void* psomething_t;
struct psomething_t MyCreateSomething(); // Does memory allocation and initialization
void MyDoSomething(psomething_t something);
#ifdef __cplusplus
}
#endif

MyApiWrapper.c

#include "ThirdParty.h"
struct psomething_t MyCreateSomething() {
psomething_t psomething = (psomething_t)CreateSomething();
return psomething;
}
void MyDoSomething(psomething_t something) {
DoSomething((struct something_t*)psomething);
}

关于您考虑的解决方案

  1. 我可以要求上游项目重命名变量,但这可能很困难

您当然应该报告该错误,让他们知道。如果是github托管的项目,请准备一个pull请求。

无论如何,要做好准备,他们可能不会及时做出回应,你应该始终有上面提到的"B计划">。不管怎样,它都会起作用。。。

  1. 我可以使用预处理器在头中重新定义类:#define class class_有任何副作用吗

如果这个特定符号(class)出现的任何地方都是纯c代码,并且第三方c代码的其他部分(例如库)不依赖于该符号(这是不可能的),那么这可能是一种可行的方式。