我正在做一个有很多遗留C代码的项目.我们已经开始用C++编写,目的是最终转换遗留代码.我对C和C++的交互有点困惑.我知道,用C的代码包extern "C",C++编译器不会损坏C个代码的名称,但我不完全知道如何实现这个代码.

因此,在每个C头文件的顶部(在Include警卫之后),我们有

#ifdef __cplusplus
extern "C" {
#endif

在底部,我们写道

#ifdef __cplusplus
}
#endif

在这两者之间,我们拥有所有的include、typedefs和function原型.我有几个问题,看看我的理解是否正确:

  1. 如果我有一个C++文件A.hh,它 包括C头文件B.h, 包括另C个头文件C.h, 这是怎么回事?我认为 当编译器步入B.H时, 将定义__cplusplus,因此它 将用extern "C"包装代码 (__cplusplus将不会是 在本挡路中定义).所以, 当它踏入C.H, 将不会定义__cplusplus 并且代码不会被包装在 extern "C".这是对的吗?

  2. 有什么不对劲吗? 使用包装一段代码 extern "C" { extern "C" { .. } }? 第二个extern "C"会是什么? 做?

  3. 我们不会把这个包装纸包在桌子上.c文件,只是.h文件.那么,如果一个函数没有原型会发生什么呢?编译器认为它是C++函数吗?

  4. 我们还使用了一些第三方软件

  5. 最后,这是一个好主意吗?

推荐答案

extern "C"实际上不会改变编译器读取代码的方式.如果您的代码在一个.c文件中,它将被编译为C,如果它在一个.cpp文件中,它将被编译为C++(除非您对您的配置做了一些奇怪的事情).

extern "C"的作用是影响链接.当编译时,C++函数的名称会被损坏——这就是使重载成为可能的原因.函数名将根据参数的类型和数量进行修改,以便具有相同名称的两个函数将具有不同的符号名.

extern "C"内部代码仍然是C++代码.在外部"C"块中可以做的事情有一些限制,但它们都是关于链接的.你不能定义任何不能用C语言构建的新符号.例如,这意味着没有类或模板.

extern "C"个街区的巢穴很漂亮.如果你发现自己无可救药地被困在extern "C"个区域内,还有extern "C++"个,但从Clean Angular 来看,这不是一个好主意.

现在,特别是关于你的编号问题:

关于#1:_cplusplus将在extern "C"个块内定义.不过,这并不重要,因为积木应该整齐地嵌套.

关于#2:将为通过C++编译器运行的任何编译单元定义__cplusplus.通常,这意味着.cpp文件以及该.cpp文件包含的任何文件.如果不同的编译单元包含相同的.h(或.hh或.hpp或What-you-you),则可以在不同的时间将它们解释为C或C++.如果您希望.h文件中的原型引用C符号名称,那么当它们被解释为C++时必须是extern "C",而当它们被解释为C时不应该是extern "C"--因此需要#ifdef __cplusplus判断.

回答你的问题#3:如果没有原型的函数在.cpp文件中,而不是在extern "C"%的挡路中,那么它们将有C++链接.不过,这很好,因为如果它没有原型,那么它只能由同一文件中的其他函数调用,而且您通常不会关心链接是什么样子的,因为无论如何您都不打算让该函数被同一编译单元之外的任何东西调用.

对于#4,你已经做到了.如果要为具有C链接的代码(例如由C编译器编译的代码)包含一个标头,那么必须将标头设置为extern "C",这样才能链接到库.(否则,当您查找void h(int, char)时,您的链接器将查找名称为_Z1hic的函数

5:这种混合是使用extern "C"的常见原因,我不认为这样做有什么错——只要确保你明白自己在做什么.

C++相关问答推荐

两个看似相同的代码的不同行为

如何从TPS特定的TGPT_PUBLIC数据 struct 中以OpenSSL的EVP_PKEY

使用sd-设备列举设备导致seg错误

如何使用Python C API实现多线程程序?

特定闪存扇区的内存别名

C:fopen是如何实现二进制模式和文本模式的?

如何在C宏中确定 struct 中元素的类型?

在一个小型玩具项目中实现终端历史记录功能

如何将长字符串转换为较小的缩写,该缩写由第一个字符、最后一个字符和中间的字符数组成?

如何使用[BTStack]BLE发送大型(>;2kb)信息包

GCC不顾-fno-Builtin-SINCOS旗帜向SINCOS发出呼唤

无法在OpenGL上绘制三角形

MacOS下C++的无阻塞键盘阅读

我可以创建适用于不同endian的 colored颜色 struct 吗?

如何在C中定义指向函数的指针并将该指针赋给函数?

在C中使用无符号整数模拟有符号整数

存储和访问指向 struct 的指针数组

C struct 中的冒泡排序

使用 GCC 将一个函数中初始化的 struct 体实例通过指针传递到 C 中的另一个函数会产生不同的结果

C 中从 Unix 纪元时间转换的损坏