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

CLe*_*ner 75 c c++ clang

我一直在使用 C++ 并使用 clang++ 进行编译。我想包含我正在编写的 X11 程序的<xcb/xkb.h>标头。

不幸的是,这个标头用于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

// ...

Run Code Online (Sandbox Code Playgroud)

Hol*_*Cat 81

使用宏重命名字段:

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

在标准 C++ 中使用关键字作为宏名称是不正确的,但 GCC、Clang(带有编译指示)和 MSVC 确实接受它。(标准说你“不应该”这样做,cppreference澄清它的意思是“格式错误”。)

  • @Peter Mhm,我在答案末尾提到了这一点。有时完全一致是不切实际的。 (21认同)

eer*_*ika 29

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

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

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


thk*_*ala 20

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

如何使用一组中间 C 文件(.c 和 .h)来包装不兼容的标头并为程序的其余部分提供 C++ 兼容接口?如果该接口足够高级,那么您只需要在包装器 .c 文件中包含不兼容的头文件,从而允许包装器 .h 头文件正常包含在 C++ 代码中。

根据详细信息,您可能最终会进行一些琐碎的数据复制,但生成的 C 接口可能更适合您的特定需求。

  • @Chuu:包装器是用 C 编写的,而不是 C++ 编写的。因此它可以调用例如名为“requires()”的函数(这是 C++20 中的关键字),只要该名称不通过其头文件公开即可。然后,它可以在其标头中公开一个名为“foo_requires()”的函数,以便在 C++ 中使用。 (4认同)