2014-09-18 112 views
1

gcc将C程序编译为C和C++程序,因此需要在C++中声明'extern“C”'。然而,g ++将C程序编译为C++,将C++程序编译为C++,因此要求在C++中不要使用'extern“C”'声明。#ifdef标志告诉gcc和g ++编译器之间的区别?

检查标准标志没有任何输入,无论是

g++ -E -dM - </dev/null 
gcc -E -dM - </dev/null 

给出了相同的结果。

__GNUG__  is equivalent to testing (__GNUC__ && __cplusplus) 

这再次将从克++ 一个C++源内不分化的gcc上市

什么是魔术

#ifndef __MAGIC_G++_INCLUDE_FLAG_BUT_NOT_GCC__ 

到环绕的extern “C”{声明?谢谢。

编辑:我知道这是一个相当深奥的情况。该测试需要在编译器上完成,而不是源代码的风味。在这两种情况下,测试都在C++源代码列表中执行(这就是为什么我提到GNUG不合适)。为了澄清,测试main.cpp中

#include <iostream> 
int 
main(int argc, char **argv) 
{ 
#ifdef __cplusplus <<<< FIX THIS ONE 
    std::cout << "I was compiled using g++" << std::endl; 
#else 
    std::cout << "I was compiled using gcc" << std::endl; 
#endif 
} 

与时任

g++ main.cpp 

或在这两种情况下

gcc main.cpp -lstdc++ 

,它似乎不正确地给作为输出“我整理是用g ++编译的“。所以看起来cplusplus不是在这种情况下使用的正确标志。我错了吗?或者什么是正确的标志?

编辑2: 谢谢,伙计们。这是你的一个例子。大型遗留系统“Alpha”主要以C语言编写,带有一点C++,并使用C++编写的大型遗留源代码包“Charlie”。它使用g ++系统进行编译和链接,并要求查理的头文件中没有外部“C”定义,否则拒绝链接。大型遗留系统“Bravo”主要以C编写,带有一点C++,并且使用与C++编写的相同的传统源代码包Charlie。它使用gcc系统进行编译和链接,并要求查理的头文件必须具有外部“C”定义,否则拒绝链接。新系统“Delta”,“Echo”和“Foxtrot”也想重用Charlie的部分源代码,编译器的使用是不确定的。正确的答案是彻底破解查理的标题,一劳永逸,用

#ifndef __MAGIC_G++_INCLUDE_FLAG_BUT_NOT_GCC__ 
extern "C" { 
#endif 
... 
declarations of code 
... 
#ifndef __MAGIC_G++_INCLUDE_FLAG_BUT_NOT_GCC__ 
} 
#endif 

然后用它做。否则总会有链接问题。是的,当然可以在这种特殊情况下编译两套库,一套在C下,另一套在C++协议下,然后规定你应该使用这个特定的库来处理这种特殊的链接。或者我可以想出两套标题。在这个例子中,这两者中的任何一个都不够优雅,并且会继续引发问题;还有其他的情况。至于g ++和gcc在底层使用同一个编译器的评论,所以它不可能很重要,可悲的是,它确实如此。当包含错误的'extern'C''教条时,整个程序包拒绝链接。是的,还有其他方法可以攻击一般问题,但这是一个简单的问题。要么存在这样的旗帜,要么已知它不存在,或者答案不明确。我不知道,我自己。

+0

有一个原因,你需要知道的?你的构建脚本/过程/等等。不是gcc/g ++编译器的标准吗? – sedavidw 2014-09-18 18:29:40

+3

您应该使用'gcc'命令编译C源文件,'g ++'命令编译C++源文件。你有这样的理由吗? – 2014-09-18 18:32:26

+0

'__cplusplus'是为C++定义的,但不适用于C语言。无论如何,两个驱动程序('gcc'和'g ++'都是真正编译器的包装器)都可以用来编译C和C++源代码,尽管它们默认使用不同的标志,最适合于C和C++。 – Deduplicator 2014-09-18 18:33:11

回答

4

的标准方法是检查预处理符号__cplusplus定义:

#ifdef __cplusplus 
extern "C" { 
#endif 

/* declarations here */ 

#ifdef __cplusplus 
} 
#endif 
+0

遗憾的是,这并未解决问题,请参阅编辑。谢谢。 – DragonLord 2014-09-18 19:58:54

+0

这是一种标准的第一顺序方法,用于填充C代码,使其适合C或C++,gcc下。它看起来不像它解决了我正在攻击的C++问题。 – DragonLord 2014-09-19 04:25:26

+0

当源代码是C而不是C++时,它能够正确地分辨两个编译器之间的区别。也就是说,如果我使用main.c而不使用main.cpp,该标志将会告诉gcc和g ++之间的区别。但是,由于extern“C”指令仅在C++中有用,因此尚不清楚这是如何解决一般问题的。 – DragonLord 2014-09-19 04:29:30

相关问题