#ifdef标志,用于区分gcc和g++;编译器? GCC将C程序编译为C++,C++程序,因此需要C++中的“外部”C“声明”。然而,G++将C程序编译为C++,C++程序作为C++,因此要求在C++中不使用“外部”C“声明”。

#ifdef标志,用于区分gcc和g++;编译器? GCC将C程序编译为C++,C++程序,因此需要C++中的“外部”C“声明”。然而,G++将C程序编译为C++,C++程序作为C++,因此要求在C++中不使用“外部”C“声明”。,c++,c,gcc,compilation,g++,C++,C,Gcc,Compilation,G++,在没有任何输入的情况下检查标准标志,包括 g++ -E -dM - </dev/null gcc -E -dM - </dev/null 再次> 不>强>将GCC与G++区分在C++源列表>/P> 魔术有什么用 #ifndef __MAGIC_G++_INCLUDE_FLAG_BUT_NOT_GCC__ 围绕外部“C”{声明?谢谢 编辑:我意识到这是一个相当深奥的例子。测试需要对编译器的味道进行,而不是源代码的味道。在这两种情况下,测试都在C++源代码列表中执行(这就是

在没有任何输入的情况下检查标准标志,包括

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

再次> <强>不>强>将GCC与G++<强>区分在C++源列表>/P> 魔术有什么用

#ifndef __MAGIC_G++_INCLUDE_FLAG_BUT_NOT_GCC__ 
围绕外部“C”{声明?谢谢

<>编辑:我意识到这是一个相当深奥的例子。测试需要对编译器的味道进行,而不是源代码的味道。在这两种情况下,测试都在C++源代码列表中执行(这就是为什么我提到GNUG是不够的)。
#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++编译的”作为输出。因此,在这种情况下,cplusplus似乎不是正确的标志。我错了吗?或者正确的标志是什么

编辑2: 谢谢大家,这里有一个例子。大型遗留系统“alpha”主要是用C编写的,使用C++,使用C++编写的大型遗留源程序包“查利”,使用G++系统编译和链接,要求查利的头没有外部“C”定义,否则拒绝链接。“Bravo”主要是用C编写的,用C++编写,也使用C++编写的同一个遗留源程序包查利,它使用GCC系统编译和链接,并要求查利的头必须有外部“C”定义,否则拒绝连接。新系统“delta”、“ECHO”和“狐步”。“还想重用来自Charlie的部分源代码,要使用的编译器是不确定的。正确的答案是使用

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

<> p>然后再处理它。否则总是会有链接问题。当然,在这个特殊的情况下,编译两个库是可能的,一个在C下,一个在C++约定下,然后命令你使用这个特定的库来连接这个特殊的连接。或者我可以想出两个。标题集。在本例中,这两个标题中的任何一个都不雅观,并且会继续导致问题;还有其他一些情况。关于g++和gcc都在幕后使用同一个编译器的评论,因此这可能不重要,遗憾的是,它确实重要。当错误的“外部”C出现时,整个包拒绝链接“包括/不包括教条。是的,有其他方法来解决一般问题,但这是一个简单的问题。要么这样的标志存在,要么已知不存在,要么答案不确定。我自己也不知道。

标准技术是检查是否定义了预处理器符号
\ucplusplus

#ifdef __cplusplus
extern "C" {
#endif

/* declarations here */

#ifdef __cplusplus
}
#endif

有没有一个原因,你需要知道吗?你的编译脚本/进程等不是GCC/G+编译器的标准吗?你应该使用<代码> GCC < /C>命令编译C源代码和<代码> G++< /C>命令来编译C++源文件。你有没有理由这样做?< C++ >代码> >无论如何,这两个驱动程序(
gcc
g++
都是真正编译器的包装器)可以使用C和C++源编译,虽然它们默认为不同的标志,最适合C和C++。如果调用GCC或G++,这并不重要。如果GCC决定源文件是C++,则编译器与G++的运行相同,即二进制Ccc1PUS是编译你的源代码的一个编译程序。如果使用GCC,则使用GCC。要编译和链接,在链接阶段是有区别的,但在编译阶段不是。如果您解释您试图解决的实际问题,可能会有所帮助。您的编辑说明了为什么这个问题没有什么意义——因为文件名为
main.cpp
,无论您是否调用命令行上的
g++
gcc
(在后一种情况下,
gcc
将为您调用
g++
),因此您总是会得到“使用g++编译”如果你想强制使用GCC不管名字,你可以使用命令行参数<代码> -x c>代码>,但是它根本就不编译,因为它不是有效的C代码。遗憾的是,这并不能解决被问到的问题,请参见Edv.Eng.谢谢。这是标准的一阶方法来使C代码变得合适,使它适合于C或C++,在GCC下。它看起来不像是我正在攻击的C++问题。它确实在两个编译器之间的差异时,在C源代码中,而不是在C++中。也就是说,如果我使用Meal.C而不是Meun.CPP,这个标志将告诉GCC和G++之间的区别。命令只在C++中有用,目前还不清楚它是如何解决一般问题的。作为一个简短的例子,在这个例子中失败了,从C中的子例程子C开始,由父Me.CPP调用。通过在定义中插入这个代码来修改它的头Health.h。这实际上对GCC编译器/链接器起作用。但是,当使用G++,T时,编译时,编译器会将孩子的对象表示悄悄地更改为C++样式,但是父进程仍然期望C样式,因为包含的报头指定了外部“C”。因此,最终的链接在G++下失败。
gcc main.cpp -lstdc++
#ifndef __MAGIC_G++_INCLUDE_FLAG_BUT_NOT_GCC__ 
extern "C" {
#endif
...
declarations of code
...
#ifndef __MAGIC_G++_INCLUDE_FLAG_BUT_NOT_GCC__ 
}
#endif
#ifdef __cplusplus
extern "C" {
#endif

/* declarations here */

#ifdef __cplusplus
}
#endif