混合C / C ++标头可以包含另一个混合标头吗?

时间:2014-09-30 14:58:43

标签: c++ c c-preprocessor

在阅读Why do we need extern "C"{ #include <foo.h> } in C++?之后,我得出结论,在extern“C”-block中包含一个标题就可以了。

但我遇到了这个星座的问题:

#ifdef __cplusplus
extern "C" {
#endif

#include "mixedstuff.h"

#ifdef __cplusplus
}
#endif

mixedstuff.h:

#ifdef __cplusplus
extern "C" {
#endif

#include "cstuff.h"

#ifdef __cplusplus
}
#include "cppstuff.h"
#endif

正如我所看到的,我最终将cppstuff.h包含在extern "C"块中的C ++编译器中。这导致了很多错误,因为C-linkage无法进行许多陈述。

显而易见的解决方案是#include mixedstuff.h块之外的extern "C"。但这需要我查看每个标题,看它是否是纯粹的 C ,C ++或混合。

从这里我建议使标题C ++知道,而不是将它们包含在extern“C”中。我是对的,还是有更好的方法?

4 个答案:

答案 0 :(得分:2)

根据您的描述,我认为mixedstuff.h已设计完成 用于C和C ++。这意味着它可能有 #ifdef __cplusplus等,在某些地方使用一些纯C ++代码。 在这种情况下,应该包含在extern "C"块中。一般而言,除非另有明确说明, 大多数标题应该包含在最外层,外面 所有块,名称空间等。一个例外是纯粹的 C标题,作者没有设计库 用于C ++;那些必须包含在extern "C"中 块。 (但是从我所看到的情况来看,这样的标题很少见 而且很少见。)

你不应该查看标题内部;你需要查看文档。

如果你是标题的作者,那么你应该让它对C ++有所了解(并记录这个事实,也许是在图书馆一级)。

答案 1 :(得分:1)

当示例告诉您将extern "C"放入自己时,就是当您包含一个仅限C的标题时。

因为它只是C语言,所以它可能用C语言编写,因此如果你想将它用于C ++,你需要将它指定为C头。

如果你有mixstuff.h它将无法在C中工作,因为它只有C ++构造。那些你想要与C链接一起使用的C结构你应该在mixstuff.h中明确标记。或者将它们隔离到自己的标题中。

请注意,与mixstuff.h一起,某处将编译mixstuff.cmixstuff.cpp,甚至可能编译两个不同的编译单元。您可以使用C ++编译器来编译实现,它们甚至可以是C ++(使用C链接)在其实现中使用C ++构造(通常是。您经常会为C ++库提供C接口)。

如果使用C ++名称修改在C ++中构建mixstuff,如果现在将extern "C"放在其声明周围,它将不会与您的代码链接。如果这些函数确实是由C编译器构建的,那么你需要使用extern "C",这样你才能看到它们。

答案 2 :(得分:1)

有各种C和C ++标准,它们有共性和差异。

如果代码是在所有目标标准的公共交集中编写的,那么只需将其包含在全局命名空间中即可。

如果在C ++中包含它时只会遗漏extern "C",请将其包装在外部。

否则,事情变得复杂,你必须直接修补它。

预处理器具有__cplusplus__STDC_VERSION__以及其他特征和语言测试宏的条件,是一种编写代码的方法,这些代码在比一般条件保证的更广泛条件下正常运行语言本身。

明智地使用它,很容易被滥用。

答案 3 :(得分:1)

如果你想确保东西有C ++链接,即使包含的头文件可能包含在extern "C"块中,你可以使用extern "C++"块:

extern "C++" {
#include "cppstuff.h"
}