我可以(在编译时)检测我是否处于 extern "C" {} 块中吗?

问题描述 投票:0回答:1

假设我有一个 C 头文件 a.h

任何 C++ 头文件,例如 #includes a.h 的 a.hpp,都应该在 extern“C”块中执行。

所以我有一些 C++ 代码和 C 代码之间通用的头文件,并且我希望所有 C++ 代码 #include 包装器加帮助器版本。

例如,如果我有“a.h”,我还有一个“a.hpp”,它在外部“C”块中 #includes a.h 并添加一些相关的 C++ 帮助程序代码。

因此我希望所有 C++ 代码#include“a.hpp”而不是“a.h”。

当然,人类就是人类,有时我们会忘记。

发生类似情况的通常信号是在链接时,因为函数名称声明被破坏,因此链接失败。

所以我想要一些可以放入 a.h 中的东西,如果 a.h 正在由 C++ 编译器编译,但不在 extern“C” 块中,则在编译时会失败。

第一部分很简单...

只需使用“#ifdef __cplusplus”

我该如何做第二部分,即在编译时检测我是否处于外部“C”块中?

c++ c static-assert extern-c
1个回答
1
投票

对于编译器来说,init 位于头文件外部或内部没有区别。编译之前完成的所有操作都会读取完整的文件。

在头文件中执行此操作的规范方法(标准库经常这样做)。

//  A new a.h

#ifdef __cplusplus
#  define EXTERN_DECL extern "C"
#  define EXTERN_SPACE_BEGIN  EXTERN_DECL  {
#  define EXTERN_SPACE_END }
#else 
#  define EXTERN_DECL extern
#  define EXTERN_SPACE_BEGIN 
#  define EXTERN_SPACE_END 
#endif

EXTERN_SPACE_BEGIN
#include "lib_includes/library_a/a.h"
EXTERN_SPACE_END 

如果您的头文件是第三方的,请从某个私有位置设置它

lib_includes
未添加到包含中并拥有自己的标头。

注意,实际上所有 POSIX 标头都会通过宏定义执行类似的操作,以同时与 C 和 C++ 兼容。

© www.soinside.com 2019 - 2024. All rights reserved.