g++和gcc有什么区别?

1157

g++和gcc有什么区别?在一般的C++开发中应该使用哪一个?

10个回答

930

gccg++是GNU编译器集合(曾经只是GNU C编译器)的编译器驱动程序。

尽管它们根据文件类型自动确定调用哪些后端(cc1 cc1plus ...),除非使用-x language进行覆盖,但它们之间存在一些差异。

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

根据GCC的在线文档链接选项g++的调用方式g++大致等同于gcc -xc++ -lstdc++ -shared-libgcc(第一个是编译器选项,后两个是链接器选项)。可以通过同时使用-v选项运行两者来进行检查(它会显示正在运行的后端工具链命令)。

默认情况下(与gcc不同),g++还会添加链接器选项-lm,用于链接libm库,该库包含了math.h的实现。

61
从这个回答中我得出结论,有效的g++命令只是带有一堆标志的gcc。那么,为什么在Linux中会有两个大小大约相同的二进制文件gcc和g++呢?难道我们不应该只有一个二进制文件和一个符号链接(或类似的东西)吗? - UchihaItachi
32
@Uchihaltachi 这些文件是硬链接,当它们被启动时会检查 argv [0] 以确定使用哪个调用。这在核心UNIX实用程序中非常常见。 - user836218
10
文档中哪里说 g++ 等同于 gcc -xc++ -lstdc++ -shared-libgcc?文档只说它将 .c、.h 和 .i 视为 C++,并自动链接 libstdc++。如果所发布的命令是正确的,那么一个包含有效 C++ 代码的 .txt 文件应该可以编译,但实际上会返回不支持的文件格式错误。 - s d
5
我会尽力进行翻译,但请注意我的能力和限制。以下是需要翻译的内容:here - somebody
2
@Lyn:也许出于与我们不仅使用带有一堆标志的g++而不是gcc相同的原因。巴达砰。 - Robin Davies
显示剩余6条评论

568

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

50
gcc 中使用参数 -lstdc++ 可以链接标准的 C++ 库。 - Denilson Sá Maia
29
“gcc”和“g++”之间的差异不仅仅在于标准库,因此使用“gcc -lstdc++”仍然不能得到与“g++”相同的行为。我们将所有特定于语言的行为放入了自己的驱动程序中,这就是它存在的原因。 :-) - Ti Strga
11
我的评论并不仅涉及链接......这就是重点。即使仅限于链接(而您的答案不是),用户仍然无法仅通过指定“-lstdc ++”来使用整个C ++标准库,因为数学、RTTI和异常信息会缺失。一个给定的测试用例是否链接或失败将取决于操作系统以及测试用例使用哪些C ++特性,这也是为什么所有这些知识都内置在g ++驱动程序中而不是留给用户自己去解决的原因。 - Ti Strga
13
相信我,我们经常会讨论这个问题,尤其是当一个Linux用户试图将他的不完整Makefile移植到另一个平台时。g++链接阶段所做的事情比在其他操作系统上使用“gcc -lstdc++”要多得多,特别是当目标平台是嵌入式平台时。幸运的是,这就是为什么我们首先提供g++的原因。 - Ti Strga
13
规范字符串是为编译器而构建的,而编译器则是针对操作系统和目标具体化的。因此,如果您在交叉编译嵌入式系统的编译器上运行“-dumpspec”,您会看到差异。这不仅仅涉及链接器的差异...正如您所回答的那样(预处理宏、包含路径、多个运行时库)。我们似乎在互相误解,但作为一名前GCC维护者,我保证我熟悉前端所涉及和未涉及的内容。 - Ti Strga
显示剩余3条评论

118

对于C++,你应该使用g++。

它是同一款编译器(例如GNU编译器集合)。 GCC或G ++只是选择不同的前端和不同的默认选项。

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


6
我的GNU/Linux gcc手册上也写着:"当你编译C++程序时,应该使用g++代替GCC。" - Elliptical view

62
什么是"g++"和"gcc"之间的区别?
"gcc"从最初的单一语言"GNU C Compiler"发展成为多语言的"GNU Compiler Collection"。在C编程的上下文中,术语"gcc"有时仍然指的是"GNU C Compiler"。
man gcc

# GCC(1)                     GNU
# 
# NAME
#        gcc - GNU project C and C++ compiler

然而,g++ 是GNU编译器集合的C++编译器。就像gnat是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++库的程序。它将.c、.h和.i文件视为C++源文件,而不是C源文件,除非使用了-x选项。当预编译具有.h扩展名的C头文件以供C++编译时,此程序也很有用。

gcc手册中搜索更多关于gccg++之间选项差异的详细信息。

一般的C++开发应该使用哪个?

从技术上讲,可以使用gccg++进行一般的C++开发,并应用相应的选项设置。然而,g++的默认行为自然与C++开发对齐。

添加了Ubuntu 18.04 'gcc' man page,并且Ubuntu 20.04继续保留以下段落:

运行GCC的常规方式是运行名为gcc的可执行文件,或在交叉编译时运行machine-gcc,或者运行特定版本的GCC时使用machine-gcc-version当编译C++程序时,应该使用g++来调用GCC。


附注:在Xcode.app嵌入的工具链中,g++只是链接到gcc。因此,g++的调用可能因工具链而异。
ls -l /Applications/Xcode.app/Contents/Developer/usr/bin
# …
# lrwxr-xr-x  1 root  wheel         3 Apr 27  2021 g++ -> gcc
# -rwxr-xr-x  1 root  wheel    167120 Nov 23 20:51 gcc

### -- versus --
which -a g++
# /usr/bin/g++
ls -l /usr/bin/g++
# -rwxr-xr-x  1 root  wheel  137616 Jan  1  2020 /usr/bin/g++

30

值得一提的是,如果你将.c文件传递给gcc编译器,它会将其编译为C语言。

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


21

尽管 gcc 和 g++ 命令执行的任务非常相似,但是 g++ 被设计成用于编译 C++ 程序;它旨在自动执行正确的操作。

实际上,它们背后使用的是同一个程序。据我了解,两者都会根据文件名扩展名决定将程序编译为 C 还是 C++。这两者都可以链接到 C++ 标准库,但只有 g++ 默认链接。因此,如果你有一个用 C++ 编写的程序,不需要链接到标准库,gcc 也能做到正确编译;但是,g++ 同样可以做到。因此,通常没有理由不使用 g++ 进行一般的 C++ 开发。


14

我对这个问题产生了兴趣,并进行了一些实验。

  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
  • 我尝试编译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
    
  • 但是当我尝试以那种方式运行"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]
    
  • 但这一个仍然可以无错误地工作

  • $ gcc -x c++ -std=c++98 test_cpp.c
    
  • 而且这也是

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

    p.s. 测试文件

    $ 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作为元工具运行良好。请参见此文档


    10
    “GCC”是GNU编译器集合的常用简称。这既是编译器的最通用名称,也是在编译C程序时使用的名称(因为这个缩写曾经代表“GNU C Compiler”)。
    当涉及到C++编译时,通常称编译器为“G++”。由于只有一个编译器,无论语言环境如何,称之为“GCC”都是准确的;然而,在编译C++程序方面,“G++”这个术语更有用。
    您可以在这里阅读更多信息。

    0
    我正在 Linux 系统中测试 gcc 和 g++。通过使用 MAKEFILE,我可以定义“GNU make”使用的编译器。我使用所谓的“动态内存”定位功能来测试 C++。
    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++”。看起来,选择g++作为C++源文件的编译器是更好的选择。


    1
    你需要完成两个任务:1. 选择语言;2. 选择一些库,例如libstdc++。 - PersianGulf

    0

    gcc和g++都是GNU编译器。它们都可以编译C和C++。不同之处在于对于*.c文件,gcc将其视为C程序,而g++则将其视为C++程序。*.cpp文件被视为C++程序。C++是C的超集,语法更加严格,因此要注意后缀。


    7
    C++是一种不同的编程语言,而不是C语言的严格超集,因此使用错误的目标语言进行编译可能会产生意外的结果。另外请注意,g++还会将.cc解释为仅限于C++的文件扩展名。 - underscore_d

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接