g++和gcc有啥区别?

Posted

技术标签:

【中文标题】g++和gcc有啥区别?【英文标题】:What is the difference between g++ and gcc?g++和gcc有什么区别? 【发布时间】:2010-09-15 09:56:42 【问题描述】:

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

【问题讨论】:

【参考方案1】:

gccg++ 是 GNU Compiler Collection(曾是 GNU C Compiler)的编译器驱动程序。

尽管它们会根据文件类型自动确定要调用的后端 (cc1 cc1plus ...),除非被 -x language 覆盖,但它们还是有一些区别。

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

根据GCC的在线文档link options和how g++ is invoked,g++相当于gcc -xc++ -lstdc++ -shared-libgcc(第一个是编译器选项,第二个两个是链接器选项)。这可以通过使用-v 选项运行两者来检查(它显示正在运行的后端工具链命令)。

【讨论】:

从这个答案中,我得出结论,实际上 g++ 命令只是带有一堆标志的 gcc .. 那么为什么在 linux 中有两个不同的二进制文件(大小大致相同)用于 gcc 和 g++? .我们不应该只有一个二进制文件和一个符号链接(或类似的东西)吗? @Uchihaltachi 这些文件是硬链接,当它们启动时,它们会检查 argv[0] 以查看应该使用哪个调用。这在核心 UNIX 实用程序中很常见。 文档中哪里说g++ is equivalent to gcc -xc++ -lstdc++ -shared-libgcc?它只是说它将 .c、.h 和 .i 视为 C++ 并自动链接 libstdc++。如果发布的命令是这种情况,则具有有效 C++ 代码的 .txt 文件将编译,但会返回不支持的文件格式错误。 这个答案是错误的。试试# include <iostream> int main ( ) std :: cout << "hello" << std :: endl ; 我希望有人可以通过gcc命令行而不是g++编译它。 here 如果仍有疑问。【参考方案2】:

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

它是同一个编译器(例如 GNU 编译器集合)。 GCC 或 G++ 只需选择具有不同默认选项的不同前端即可。

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

【讨论】:

+1 我的 GNU/Linux gcc 手册页也说:“当你编译 C++ 程序时,你应该调用 GCC 作为 g++。”【参考方案3】:

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

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

【讨论】:

(晚了,但为了后代,)正如其他答案所指出的,这绝不是“唯一显着的区别”,除非读者对知名度的定义有偏差。【参考方案4】:

虽然 gcc 和 g++ 命令做的事情非常相似,但 g++ 被设计为您在编译 C++ 程序时调用的命令;它旨在自动做正确的事情。

在幕后,它们实际上是同一个程序。据我了解,两者都根据文件扩展名决定将程序编译为 C 还是 C++。两者都能够链接到 C++ 标准库,但默认情况下只有 g++ 这样做。因此,如果您有一个用 C++ 编写的程序,并且碰巧不需要链接到标准库,那么 gcc 会碰巧做正确的事情;但是,g++ 也会如此。所以真的没有理由不使用 g++ 进行一般的 C++ 开发。

【讨论】:

【参考方案5】:

GCC:GNU 编译器集合

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

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

主要区别:

    gcc 将编译:*.c\*.cpp 文件分别为 C 和 C++。 g++ 将编译:*.c\*.cpp 文件,但它们都将被视为 C++ 文件。 此外,如果您使用 g++ 链接目标文件,它会自动链接到标准 C++ 库中(gcc 不会这样做)。 gcc 编译 C 文件的预定义宏更少。 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

【讨论】:

可以通过-lstdc++参数链接gcc中的std C++库。 'gcc' 和 'g++' 之间的区别不仅仅是标准库,所以gcc -lstdc++ 仍然无法获得与g++ 相同的行为。我们将所有特定于语言的行为放入其自己的驱动程序中是有原因的,这就是它的用途。 :-) 我的评论不仅仅是在谈论链接......这就是重点。即使只是将讨论限制为链接(您的答案不是),用户仍然将无法通过仅指定 -lstdc++ 来使用整个 C++ 标准库,因为将会缺少依赖项关于数学、RTTI 和异常信息。给定的测试用例是否链接或失败将取决于操作系统以及测试用例使用了哪些 C++ 功能,这也是为什么所有这些知识都内置到 g++ 驱动程序中而不是留给用户自己弄清楚的原因. 相信我,我们经常讨论这个问题,通常是当 Linux 用户试图将他不完整的 Makefile 移动到另一个平台时。 :-) g++ 链接阶段在其他操作系统上比gcc -lstdc++ 做得更多,尤其是当目标是嵌入式平台时。幸运的是,这就是我们首先发布 g++ 的原因。 规范字符串被构造为特定于编译器,而编译器又特定于操作系统和目标。因此,如果您在(例如)针对嵌入式系统的交叉编译器上运行-dumpspec,您将看到差异。不仅仅是链接器的差异......这也是您的答案(预处理器宏、包含路径、多个运行时库)。我们似乎在谈论对方,但作为一名前 GCC 维护者,我向你保证,我熟悉前端是什么和不是什么。【参考方案6】:

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

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

你可以阅读更多here。

【讨论】:

【参考方案7】:

gcc 和 g++ 都是 GNU 编译器。他们都编译c和c++。不同之处在于 *.c 文件 gcc 将其视为 c 程序,而 g++ 将其视为 c ++ 程序。 *.cpp 文件被认为是 c++ 程序。 c++是c的超集,语法比较严格,所以要注意后缀。

【讨论】:

C++ 是一种不同的语言,而不是 C 的严格超集,因此使用错误的目标语言进行编译很可能会产生意想不到的结果。另请注意,g++ 还将 .cc 解释为仅限 C++ 的文件扩展名。【参考方案8】:

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

    我找到了那个描述here,但是很短。

    然后我尝试在我的 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 
    

附言测试文件

$ 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 : intred,green,blue; // scoped enum
int main()

    std::vector<int> a 1,2,3; // bracket initialization
    return 0;

调查结果:

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

    如果你有正确的扩展名或设置正确,gcc 可以作为元工具正常工作 -std -x 标志。见this

【讨论】:

【参考方案9】:

g++gcc有什么区别?

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

man gcc

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

不过,g++ GNU Compiler Collection 的 C++ 编译器。就像gnatgcc 的Ada 编译器。 see Using the GNU Compiler Collection (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 的常用方法是在交叉编译时运行名为 gccmachine-gcc 的可执行文件,或者在运行特定版本的 GCC 时运行 machine-gcc-version当你编译 C++ 程序时,你应该调用 GCC 作为 g++

【讨论】:

【参考方案10】:

我在 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++

以上是关于g++和gcc有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章

GCC -g vs -g3 GDB 标志:有啥区别?

G++和GCC和C,C++有啥区别的

“gcc -s”和“strip”命令有啥区别?

gcc和msvc(或Linux和Windows)中的valarray有啥区别

-m32、-m64 和 gcc 选项中的任何内容有啥区别?

-symbolic 和 -shared GCC 标志之间有啥区别?