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

Tim*_*ann 14 c c++

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

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

#ifdef __cplusplus
extern "C" {
#endif

struct something_t {
    ...
    sometype class;
};


#ifdef __cplusplus
}
#endif
Run Code Online (Sandbox Code Playgroud)

g ++不喜欢这个并抱怨"错误:'之前的预期标识符';' 令牌".

我有什么选择?

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

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

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

use*_*042 13

正如其他人在评论中已经提到的那样,最好的选择是围绕那些东西编写另一个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
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

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);
}
Run Code Online (Sandbox Code Playgroud)

关于您考虑的解​​决方案

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

你当然应该报告这个bug让他们知道.如果它是一个git-hub托管项目,则准备一个pull请求.

无论如何,他们准备好他们可能没有及时回应,你应该总是有上面提到的"计划B".它会工作,不管......

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

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

  • @Voo TBF他们的标题代码中有这些奇怪的`#ifdef __cplusplus`守卫.关于这个强烈的提示,它应该与c ++编译器兼容,这可以被认为是我所说的错误. (8认同)
  • @StephenG那么你会接受针对你的C++库的错误报告,告诉你你正在使用受限制的FORTRAN关键字并请尽管名称最合适,请重命名吗?我们必须告诉人们C和C++一直是两种不同的语言,这只是这一事实的一个结果.当然,如果维护者很好,他们可能希望让你的生活更轻松,但它肯定不是原始项目中的错误 - 这是一个功能请求. (7认同)
  • @Voo坦率地说,任何进行库编码并使用像"类"这样的名称作为变量名称的人都需要他们的屁股踢 - 这就是问题.库应该尝试使用例如这样的变量名的前缀(例如,对于名为foo的库,foo_class和foo_handle).这是尝试避免名称冲突的基本编程常识.使用主要语言关键字只是双重愚蠢,我个人认为这是一个错误.因人而异. (2认同)