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''教条时,整个程序包拒绝链接。是的,还有其他方法可以攻击一般问题,但这是一个简单的问题。要么存在这样的旗帜,要么已知它不存在,或者答案不明确。我不知道,我自己。
有一个原因,你需要知道的?你的构建脚本/过程/等等。不是gcc/g ++编译器的标准吗? – sedavidw 2014-09-18 18:29:40
您应该使用'gcc'命令编译C源文件,'g ++'命令编译C++源文件。你有这样的理由吗? – 2014-09-18 18:32:26
'__cplusplus'是为C++定义的,但不适用于C语言。无论如何,两个驱动程序('gcc'和'g ++'都是真正编译器的包装器)都可以用来编译C和C++源代码,尽管它们默认使用不同的标志,最适合于C和C++。 – Deduplicator 2014-09-18 18:33:11