如何在 C + + 中包含使用 C + + 关键字作为标识符的 C 头?

我一直在用 C + + 和 clang + + 进行编译。我想包括 < xcb/xkb.h > 头为一个 X11程序我写的。

不幸的是,这个头对一些字段名使用 explicit(例如第727行) ,这是 C + + 中的关键字。

有办法解决这个问题吗?

Xcb/xkb.h :

// ...


#ifdef __cplusplus
extern "C" {
#endif


// ...


typedef struct xcb_xkb_set_explicit_t {
xcb_keycode_t keycode;
uint8_t       explicit;
} xcb_xkb_set_explicit_t;


// ...


#ifdef __cplusplus
}
#endif


// ...


6028 次浏览

使用宏重命名字段:

#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wkeyword-macro"
#endif
#define explicit explicit_
#ifdef __clang__
#pragma clang diagnostic pop
#endif


#include <xcb/xkb.h>


#undef explicit

使用关键字作为宏名称是 标准 C + + 中的病态格式,但是 GCC、 Clang (使用杂注)和 MSVC 都接受它。(标准说你“不应该”这样做,首选 澄清一下,它的意思是“形式不正确”。)

如何在 C + + 中包含使用 C + + 关键字作为标识符的 C 头?

没有符合标准的解决方案能够包括这样的头。为了能够在 C + + 中包含一个头文件,它必须用有效的 C + + 编写。对于 C 头,因此必须用 C 和 C + + 的公共子集来编写。

理想的解决方案是将头部修改为有效的 C + + 。一个符合标准的解决方案是用 C 编写一个符合 C + + 的包装器。

(不是确切问题的答案,但可能对 C & C + + 接口的一般问题有用)

如何使用一个中间的 C 文件集(。C & .H)包装不兼容的头部并为程序的其余部分提供一个 C + + 兼容的接口?如果该接口的级别足够高,那么您只需要在包装器中包含不兼容的头文件。只有 c 文件,允许包装。H 头文件通常包含在 C + + 代码中。

根据细节的不同,您可能最终只需要进行一些琐碎的数据复制,但是最终的 C 接口可能更适合您的特定需求。

一种解决方案是向 makefile 添加一个生成步骤,该步骤复制标头并重命名字段,并包含所述自动生成的标头。

(这在一般情况下是很难做到的,但在这种情况下,头部不太可能使用 explicit做任何其他事情,即使只是一个简单的(Gnu) sed(s/\bexplicit\b/explicit_field/g或类似的)将工作。更棘手的是找出要复制的正确文件。)

确保复制头的位置是包含路径中的原始头 之前,以防包含中的其他内容间接包含头。

仅仅更改字段名不应该对 ABI 有任何影响,至少对名义上与 C 兼容的头部不应该有任何影响。(在 C + + 中有些情况下,重命名一个字段确实会影响到一些事情。)