g ++和gcc有什么区别?


875

g ++和gcc有什么区别?其中哪一个应该用于一般的c ++开发?


g ++ => c ++编译器gcc => c编译器
Nagappa

Answers:


727

gcc并且g++是GNU编译器编译器的驱动程序(这是很久以前就在GNU C编译器)。

即使它们cc1 cc1plus根据文件类型自动确定要调用的后端(...),除非用覆盖-x language,它们还是会有一些差异。

它们默认值中最重要的区别是它们自动链接到的库。

根据GCC的在线文档的链接选项以及如何G ++调用g++相当于gcc -xc++ -lstdc++ -shared-libgcc(第1是一个编译器选项,第二两个是连接选项)。可以通过同时运行两个-v选项进行检查(它显示正在运行的后端工具链命令)。


13
从这个答案中,我得出结论,有效的g ++命令只是带有一堆标志的gcc ..为什么在Linux中gcc和g ++有两个不同的二进制文件(大小大致相同)?我们不应该只有一个二进制文件和一个符号链接(或类似的东西)吗?
UchihaItachi

9
@Uchihaltachi这些文件是硬链接,在启动时会检查argv[0]应使用哪个调用。这在核心UNIX实用程序中非常普遍。
津津乐道

438

GCC:GNU编译器集合

  • 引用GNU编译器支持的所有不同语言。

gcc:GNU C编译器
g++:GNU C ++编译器

主要区别:

  1. gcc将编译:*.c\*.cpp文件分别为C和C ++。
  2. g++将编译:*.c\*.cpp文件,但它们都将被视为C ++文件。
  3. 另外,如果g++用于链接目标文件,它会自动链接到std C ++库中(gcc不这样做)。
  4. gcc 编译C文件具有较少的预定义宏。
  5. gcc编译*.cppg++编译*.c\*.cpp文件还有一些额外的宏。

编译*.cpp文件时的额外宏:

#define __GXX_WEAK__ 1
#define __cplusplus 1
#define __DEPRECATED 1
#define __GNUG__ 4
#define __EXCEPTIONS 1
#define __private_extern__ extern

37
您可以gcc通过传递-lstdc++参数来链接std C ++库。
DenilsonSáMaia 2010年

16
“ gcc”和“ g ++”之间的区别不仅仅限于标准库,因此gcc -lstdc++仍然无法获得与相同的行为g++。出于某种原因,我们将所有特定于语言的行为放入其自己的驱动程序中。:-)
Ti Strga

8
我的评论不是在谈论仅仅链接……这就是重点。即使只是将讨论限制为链接(您的回答不是),用户仍然只能通过指定来使用整个C ++标准库-lstdc++,因为对数学,RTTI和异常信息的依赖将丢失。给定的测试用例是链接还是失败将取决于操作系统以及测试用例使用的C ++功能,这也是为什么所有这些知识都内置在g ++驱动程序中而不是由用户自己弄清楚的原因。 。
Ti Strga

10
相信我,我们经常进行这种讨论,通常是当Linux用户尝试将其不完整的Makefile移至另一个平台时。:-) g ++链接阶段的功能比gcc -lstdc++其他OS 还要多,尤其是当目标是嵌入式平台时。幸运的是,这就是为什么我们首先发布g ++的原因。
Ti Strga

10
规范字符串被构造为特定于编译器,而编译器又特定于操作系统和目标。因此,如果您-dumpspec在(例如)针对嵌入式系统的交叉编译器上运行,您将看到不同之处。不仅仅是链接器差异……这又是您的答案(预处理器宏,包含路径,多个运行时库)。我们似乎彼此交谈,但是作为前GCC维护者,我向您保证我对前端的了解和不了解。
Ti Strga

82

对于c ++,您应该使用g ++。

它是相同的编译器(例如GNU编译器集合)。GCC或G ++只是选择具有不同默认选项的其他前端。

简而言之:如果您使用g ++,那么前端将告诉链接器您可能想与C ++标准库链接。gcc前端不会这样做(如果您传递了正确的命令行选项,它也可以与它们链接)。


3
+1我的GNU / Linux gcc手册页还说:“编译C ++程序时,应改为将GCC作为g ++来调用。”
椭圆视图

35

g++和之间有什么区别gcc

gcc已从单一语言“ GNU C编译器”演变为多语言“ GNU编译器集合”。有时仍在C编程的上下文中使用术语“ GNU C编译器”。

g++ 对GNU编译器的C ++编译器。就像gnatAda的Ada编译器一样gcc请参阅使用GNU编译器集合(GCC)

例如,Ubuntu 16.04和18.04 man g++命令返回GCC(1)手册页。

Ubuntu 16.04和18.04 man gcc指出...

g++ 接受与以下选项基本相同的选项 gcc

而默认...

...的使用gcc不会添加C ++库。 g++是一个调用GCC并自动指定针对C ++库的链接的程序。除非使用-x,否则它将.c,.h和.i文件视为C ++源文件而不是C源文件。当预编译带有.h扩展名的C头文件以用于C ++编译时,该程序也很有用。

gcc手册页中搜索有关gcc和之间选项差异的更多详细信息g++

通用c ++开发应使用哪一个?

从技术上讲,gcc或者g++可以使用适当的选项设置将其用于常规C ++开发。但是,g++默认行为自然会与C ++开发保持一致。

Ubuntu的18.04手册页添加了以下段落:

运行GCC的通常方法是运行名为的可执行文件gcc,或者machine-gcc在进行交叉编译时machine-gcc-version运行,或者运行特定版本的GCC。 编译C ++程序时,应g++改为调用GCC 。


21

一个显着的区别是,如果将.c文件传递给gcc,它将编译为C。

g ++的默认行为是将.c文件视为C ++(除非-x c指定)。


19
(后来,但为了后代)正如其他答案所指出的那样,这绝不是“唯一的显着差异”,除非读者对显着性的定义有偏见。
underscore_d

16

尽管gcc和g ++命令做的事情非常相似,但g ++被设计为您用来编译C ++程序的命令。它旨在自动执行正确的操作。

在后台,它们实际上是相同的程序。据我了解,两者都基于文件扩展名决定是将程序编译为C还是C ++。两者都可以针对C ++标准库进行链接,但是默认情况下,只有g ++可以这样做。因此,如果您有一个用C ++编写的程序不需要碰巧与标准库链接,则gcc会做正确的事。但是g ++也是如此。因此,实际上没有理由不将g ++用于一般的C ++开发。


12

我对此问题感兴趣并进行了一些实验

  1. 我在这里找到了描述,但是它很短。

  2. 然后,我尝试在Windows计算机上尝试使用gcc.exe和g ++。exe:

    $ g++ --version | head -n1 
    g++.exe (gcc-4.6.3 release with patches [build 20121012 by perlmingw.sf.net]) 4.6.3
    
    $ gcc --version | head -n1
    gcc.exe (gcc-4.6.3 release with patches [build 20121012 by perlmingw.sf.net]) 4.6.3
  3. 我尝试编译c89,c99和c ++ 1998简单的测试文件,并且对我来说很好,因为正确的扩展名与语言匹配

    gcc -std=c99 test_c99.c
    gcc -std=c89 test_c89.c 
    g++ -std=c++98 test_cpp.cpp
    gcc -std=c++98 test_cpp.cpp
  4. 但是,当我尝试以这种方式运行“ gnu编译器集合”工具时:

    $ gcc -std=c++98 test_cpp.c
    cc1.exe: warning: command line option '-std=c++98' is valid for C++/ObjC++ but not for C [enabled by default]
  5. 但这仍然可以正常工作

    $ gcc -x c++ -std=c++98 test_cpp.c
  6. 这也

    $ g++ -std=c++0x test_cpp_11.cpp 

ps测试文件

$ cat test_c89.c test_c99.c test_cpp.cpp

// C89 compatible file
int main()
{
    int x[] = {0, 2};
    return sizeof(x);
}

// C99 compatible file
int main()
{
    int x[] = {[1]=2};
    return sizeof(x);
}

// C++1998,2003 compatible file
class X{};
int main()
{
    X x;
    return sizeof(x);
}

// C++11
#include <vector>
enum class Color : int{red,green,blue}; // scoped enum
int main()
{
    std::vector<int> a {1,2,3}; // bracket initialization
    return 0;
}

发现:

  1. 如果看进程树,那么看来gcc和g ++是其他工具的后端,在我的环境中是:cc1plus.exe,cc1.exe,collect2.exe,as.exe,ld.exe

  2. 如果您具有正确的扩展名或设置了正确的-std -x标志,则gcc可以很好地用作metatool。看到这个


9

“ GCC”是GNU编译器集合的常用缩写。这既是编译器的最通用名称,也是强调编译C程序时使用的名称(以前的缩写是“ GNU C Compiler”的缩写)。

当提到C ++编译时,通常将编译器称为“ G ++”。由于只有一个编译器,因此无论什么语言环境,都将其称为“ GCC”也很准确。但是,当重点放在编译C ++程序时,术语“ G ++”更有用。

您可以在这里阅读更多内容。


0

我正在Linux系统中测试gcc和g ++。通过使用MAKEFILE,我可以定义“ GNU make”使用的编译器。我通过“ C plus plus”的所谓“动态内存”定位功能进行了测试:

int main(){

int * myptr = new int;
* myptr = 1;
printf("myptr[0] is %i\n",*myptr);
return 0;
}

只有g ++可以在我的计算机上成功编译,而gcc会报告错误

undefined reference to `operator new(unsigned long)'

因此,我自己的结论是gcc不完全支持“ C plus plus”。似乎为C ++源文件选择g ++是更好的选择。


您必须做两项工作:1.选择语言2.选择一些库文件作为libstdc ++
PersianGulf

-1

gcc和g ++都是GNU编译器。他们都编译c和c ++。区别在于* .c文件gcc将其视为ac程序,而g ++则将其视为ac ++程序。* .cpp文件被认为是c ++程序。c ++是c的超集,并且语法更加严格,因此请注意后缀。


1
C ++是另一种语言,而不是C的严格超集,因此使用错误的目标语言进行编译很可能会产生意外的结果。另请注意,g++这也将解释.cc为仅C ++的文件扩展名。
underscore_d
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.