gcc将C程序编译为C,将C ++程序编译为C ++,因此需要在C ++中使用“extern”C“'声明。然而,g ++将C程序编译为C ++,将C ++程序编译为C ++,因此要求'extern“C”'声明不得在C ++中使用。
检查没有任何输入的标准标志,
g++ -E -dM - </dev/null
gcc -E -dM - </dev/null
给出相同的结果。
__GNUG__ is equivalent to testing (__GNUC__ && __cplusplus)
同样不将gcc与C ++源代码清单中的g ++ 区分开来。
的魔力是什么?
#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 ++系统进行编译和链接,并要求Charlie的头文件中没有外部的“C”定义,否则它会拒绝链接。大型遗留系统“Bravo”主要用C语言编写,带有一点点C ++,并且还使用了用C ++编写的相同遗留源包Charlie。它使用gcc系统进行编译和链接,并要求Charlie的头文件中必须包含extern“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 :(得分:5)
标准技术是检查是否定义了预处理器符号__cplusplus
:
#ifdef __cplusplus
extern "C" {
#endif
/* declarations here */
#ifdef __cplusplus
}
#endif