0

我对 C 和 C++ 中的预处理器指令有疑问。

我有以下代码:

#ifdef __cplusplus
//part A
extern "C" 
{
// somecode here
}
#else
//part B
#endif

我知道 c++ 编译器预定义了 __cplusplus 将 c 编译器没有。

而我把这组代码放到了ac头文件中,c++文件中就会包含这个c头文件。我的问题是:如果文件是由c++编译器编译的,它会编译A部分,如果它是由ac编译器编译的,它会编译B部分,但通常,我们使用这段代码来制作c++文件和c文件相互交互,如果我们上面有这样的代码,我的意思是我们同时拥有C和C++文件,并且我们使用gcc编译器,这段代码是如何编译的?只有A部分被编译?还是只编译 B 部分?还是代码分为两部分,A部分为C++编译,B部分同时为C文件编译?

4

5 回答 5

2

如果我们上面有这样的代码,我的意思是我们同时拥有 C 和 C++ 文件,并且我们使用 gcc 编译器,这段代码是如何编译的?只有A部分被编译?还是只编译 B 部分?

这取决于#includes 标头的翻译单元是如何编译的。如果编译为C++,则A部分生效;如果它被编译为 C,它将是 B 部分。

使用gcc,语言要么由文件扩展名确定,要么可以在命令行上显式指定:

-x language

明确指定以下输入文件的语言(而不是让编译器根据文件名后缀选择默认语言)。此选项适用于所有后续输入文件,直到下一个-x选项。

语言的可能值为: c c-header c-cpp-output c++ c++-header c++-cpp-output Objective-c Objective-c-header Objective-c-cpp-output Objective-c++ Objective-c++-header Objective-c++ -cpp-输出汇编器 汇编器-with-cpp ada f77 f77-cpp-input f95 f95-cpp-input java

于 2012-12-04T20:27:31.027 回答
2

直接回答:只编译适合当前编译器调用的部分。

通常结构是

#ifdef __cplusplus
extern "C" {
#endif
/* Definitions here */
#ifdef __cplusplus
}
#endif

在头文件中。因此,您可以获得两种语言的兼容定义。然后,实现文件将是纯 C 并存储在 .c 文件中。

于 2012-12-04T20:30:46.323 回答
0

在具有多个源文件的项目中,编译器不会只处理一次标头。

当编译器编译 C++ 文件时,它会读取该文件及其包含的任何头文件(直接或间接),并使用 C++ 规则处理这些文件的内容。

当编译器编译 C 文件时,它会读取该文件及其包含的任何头文件(直接或间接),并使用 C 规则处理这些文件的内容。

结果就像头文件中的代码分别出现在 C++ 源代码和 C 源代码中一样。

于 2012-12-04T20:53:49.443 回答
0

从概念上讲,C++ 通过修饰标识符转换为 C 代码。这将影响链接。(事实上​​,这是过去的做法,如果我没记错的话,它是由CFront完成的。

所以有

#ifdef __cplusplus
   extern "C" {
#endif
   /* Definitions here */
#ifdef __cplusplus
}
#endif

C 和 C++ 的定义相同。您不想要不同的(问题中的 A 和 B 部分),因为那很愚蠢。如果您将它用于 C 和 C++,那么您就是一样的。

extern "C"位告诉 C++ 编译器确保链接是针对为 C 编译的目标代码 - 因此不要使用 C++ 魔术,从而确保链接能够正常工作。

于 2012-12-04T20:37:44.540 回答
0

默认情况下,gcc 会将,.C和其他一些扩展识别为 C++ 和C。您可以在 make 文件中尝试更有趣的东西来强制它通过每种方式,但在简单的情况下,就这么简单。.cpp.cc.c

于 2012-12-04T20:28:03.977 回答