zhcn 编程语言 非公開: gcc 和 g++ 有什么区别?

gcc 和 g++ 有什么区别?

GCC编译器自开发以来(2020年6月)已更新至10.1.0版本,虽然最初只能编译C语言,但其功能已扩展为能够编译包括C++在内的多种编程语言。

目前的 GCC 编译器还支持编译 Go、Objective-C、Objective-C++、Fortran、Ada、D 和 BRIG (HSAIL) 等程序,甚至 GCC 6 及更早版本都可以编译 Java 程序。不过,由于本文主要描述了如何使用GCC编译器来编译和运行C和C++程序,因此并没有详细介绍如何使用GCC编译器来编译其他编程语言。

那么,假设你已经编辑了C或C++代码,你如何调用GCC编译器来编译你的程序呢?很简单,GCC编译器为我们提供了调用它的接口,对于C或C++程序,可以通过执行gcc或g++指令来调用GCC编译器。

注意,在实际使用中,我们习惯使用gcc指令来编译C语言程序,使用g++指令来编译C++代码。我应该强调,这不是 gcc 和 g++ 之间的区别。 gcc指令也可以用来编译C++程序,g++指令也可以用来编译C语言程序。

那么gcc和g++有什么区别呢?接下来我们将为读者详细讲解。

其实只要你的程序代码是用GCC编译的,就可以使用gcc命令来完成编译。你可以理解为gcc是GCC编译器的通用编译指令。这是因为gcc指令可以根据程序文件的后缀名来判断当前程序使用的编程语言的类型。例如:

  • xxx.c:编译C语言程序默认编译该文件。
  • xxx.cpp:按照默认编译C++程序的方式编译该文件。
  • xxx.m:编译Objective-C程序时默认编译该文件。
  • xxx.go:默认情况下,该文件的编译方式与Go语言程序的编译方式相同。

当然,gcc命令还为用户提供了“手动指定典型编译方法”的接口,即使用-x选项。例如,gcc -xc xxx 表示按照编译 C 语言代码的方式编译 xxx 文件,gcc -xc++ xxx 表示按照编译 C++ 代码的方式编译 xxx 文件。稍后将提供如何使用 -x 选项的具体示例。

但是,当您使用 g++ 命令时,无论目标文件的后缀是什么,该命令都会像编译 C++ 代码一样编译该文件。也就是说,对于.c文件,gcc指令被视为C语言代码,g++指令被视为C++代码。但是,对于 .cpp 文件,gcc 和 g++ 都编译为 C++ 代码。

由于C++与C语言兼容,因此使用gcc或g++编译C程序应该没有区别,但事实并非如此。严格来说,C++标准和C语言标准的语法要求是不同的。例如:

 
//ファイル demo.c 
#include <stdio.h>
int main()
{
    const char * a = "abc";
    printStr(a);
    return;
}
int printStr(const char* str)
{
    printf(str);
} 

如上所示,这是非标准的C语言代码。当使用 gcc 指令编译时,如下所示:

[root@bogon ~]# gcc -xc demo.c #或者直接运行 gcc demo.c
[root@bogon ~]#

可以看到执行指令时没有发生错误。使用 g++ 指令编译相同的程序会导致:

[root@bogon ~]# g++ demo.c
demo.c:在函数“int main()”中:
demo.c:5: 错误: ‘printStr’ 未在此范围内声明
demo.c:6: 错误:返回语句没有值,在返回“int”的函数中
[root@bogon ~]#

正如您所看到的,GCC 编译器检测到三个错误。显然,C++标准对于代码编写规范有着更加严格的要求。

此外,使用 gcc 和 g++ 编译和运行 C++ 程序之间也存在差异。许多C++程序都会调用标准库中现有的函数或类对象,但是您应该知道简单的gcc命令无法自动链接这些标准库文件。例如:

 
//demo.cpp
#include <iostream>
#include <string>
using namespace std;

int main(){
    string str ="IT基礎";
    cout << str << endl;
    return 0;
} 

这是一个非常简单的C++程序,通过<string>头文件提供的字符串类定义字符串对象,并使用cout输出流对象输出。使用 g++ 指令编译此 C++ 代码会产生以下结果:

[root@bogon ~]# g++ demo.cpp
[root@bogon ~]#

可以看到整个编译过程没有报错。然而,当使用gcc指令时:

[root@bogon ~]# gcc demo.cpp
/tmp/ccIOnwra.o:在函数“main”中:
demo.cpp:(.text+0x13): 对 `std::allocator 的未定义引用::分配器()’
未定义的引用
#跳过许多错误消息

读者可以自行编译,会收到很多错误信息。根本原因是程序使用了标准库<iostream>和<string>提供的类对象,但gcc默认找不到它们。

如果使用gcc命令编译运行C++程序,则在使用gcc命令时必须手动添加-lstdc++ -shared-libgcc选项。这意味着gcc在编译C++程序时可以链接所需的C++标准库。程序。也就是说,您可以像这样编译 demo.cpp 文件:

[root@bogon ~]# gcc -xc++ demo.cpp -lstdc++ -shared-libgcc
[root@bogon ~]#

因此,demo.cpp编译成功。

读者可能会认为 g++ 命令等同于gcc -xc++ -lstdc++ -shared-libgcc命令。显然后者写起来非常乏味,大多数人更喜欢前者。

gcc和g++指令还有其他详细的区别,这里不再赘述。读完本节后,您只需知道需要使用gcc命令来编译C语言程序。我们还建议使用 g++ 命令来编译 C++ 程序。这就够了。

那么如何运行成功编译的 C 或 C++ 程序并查看结果呢?我们将在下一章详细探讨这一点。

GCC编译器自开发以来(2020年6月)已更新至10.1.0版本,虽然最初只能编译C语言,但其功能已扩展为能够编译包括C++在内的多种编程语言。

目前的 GCC 编译器还支持编译 Go、Objective-C、Objective-C++、Fortran、Ada、D 和 BRIG (HSAIL) 等程序,甚至 GCC 6 及更早版本都可以编译 Java 程序。不过,由于本文主要描述了如何使用GCC编译器来编译和运行C和C++程序,因此并没有详细介绍如何使用GCC编译器来编译其他编程语言。

那么,假设你已经编辑了C或C++代码,你如何调用GCC编译器来编译你的程序呢?很简单,GCC编译器为我们提供了调用它的接口,对于C或C++程序,可以通过执行gcc或g++指令来调用GCC编译器。

注意,在实际使用中,我们习惯使用gcc指令来编译C语言程序,使用g++指令来编译C++代码。我应该强调,这不是 gcc 和 g++ 之间的区别。 gcc指令也可以用来编译C++程序,g++指令也可以用来编译C语言程序。

那么gcc和g++有什么区别呢?接下来我们将为读者详细讲解。

其实只要你的程序代码是用GCC编译的,就可以使用gcc命令来完成编译。你可以理解为gcc是GCC编译器的通用编译指令。这是因为gcc指令可以根据程序文件的后缀名来判断当前程序使用的编程语言的类型。例如:

  • xxx.c:编译C语言程序默认编译该文件。
  • xxx.cpp:按照默认编译C++程序的方式编译该文件。
  • xxx.m:编译Objective-C程序时默认编译该文件。
  • xxx.go:默认情况下,该文件的编译方式与Go语言程序的编译方式相同。

当然,gcc命令还为用户提供了“手动指定典型编译方法”的接口,即使用-x选项。例如,gcc -xc xxx 表示按照编译 C 语言代码的方式编译 xxx 文件,gcc -xc++ xxx 表示按照编译 C++ 代码的方式编译 xxx 文件。稍后将提供如何使用 -x 选项的具体示例。

但是,当您使用 g++ 命令时,无论目标文件的后缀是什么,该命令都会像编译 C++ 代码一样编译该文件。也就是说,对于.c文件,gcc指令被视为C语言代码,g++指令被视为C++代码。但是,对于 .cpp 文件,gcc 和 g++ 都编译为 C++ 代码。

由于C++与C语言兼容,因此使用gcc或g++编译C程序应该没有区别,但事实并非如此。严格来说,C++标准和C语言标准的语法要求是不同的。例如:

 
//ファイル demo.c 
#include <stdio.h>
int main()
{
    const char * a = "abc";
    printStr(a);
    return;
}
int printStr(const char* str)
{
    printf(str);
} 

如上所示,这是非标准的C语言代码。当使用 gcc 指令编译时,如下所示:

[root@bogon ~]# gcc -xc demo.c #或者直接运行 gcc demo.c
[root@bogon ~]#

可以看到执行指令时没有发生错误。使用 g++ 指令编译相同的程序会导致:

[root@bogon ~]# g++ demo.c
demo.c:在函数“int main()”中:
demo.c:5: 错误: ‘printStr’ 未在此范围内声明
demo.c:6: 错误:返回语句没有值,在返回“int”的函数中
[root@bogon ~]#

正如您所看到的,GCC 编译器检测到三个错误。显然,C++标准对于代码编写规范有着更加严格的要求。

此外,使用 gcc 和 g++ 编译和运行 C++ 程序之间也存在差异。许多C++程序都会调用标准库中现有的函数或类对象,但是您应该知道简单的gcc命令无法自动链接这些标准库文件。例如:

 
//demo.cpp
#include <iostream>
#include <string>
using namespace std;

int main(){
    string str ="IT基礎";
    cout << str << endl;
    return 0;
} 

这是一个非常简单的C++程序,通过<string>头文件提供的字符串类定义字符串对象,并使用cout输出流对象输出。使用 g++ 指令编译此 C++ 代码会产生以下结果:

[root@bogon ~]# g++ demo.cpp
[root@bogon ~]#

可以看到整个编译过程没有报错。然而,当使用gcc指令时:

[root@bogon ~]# gcc demo.cpp
/tmp/ccIOnwra.o:在函数“main”中:
demo.cpp:(.text+0x13): 对 `std::allocator 的未定义引用::分配器()’
未定义的引用
#跳过许多错误消息

读者可以自行编译,会收到很多错误信息。根本原因是程序使用了标准库<iostream>和<string>提供的类对象,但gcc默认找不到它们。

如果使用gcc命令编译运行C++程序,则在使用gcc命令时必须手动添加-lstdc++ -shared-libgcc选项。这意味着gcc在编译C++程序时可以链接所需的C++标准库。程序。也就是说,您可以像这样编译 demo.cpp 文件:

[root@bogon ~]# gcc -xc++ demo.cpp -lstdc++ -shared-libgcc
[root@bogon ~]#

因此,demo.cpp编译成功。

读者可能会认为 g++ 命令等同于gcc -xc++ -lstdc++ -shared-libgcc命令。显然后者写起来非常乏味,大多数人更喜欢前者。

gcc和g++指令还有其他详细的区别,这里不再赘述。读完本节后,您只需知道需要使用gcc命令来编译C语言程序。我们还建议使用 g++ 命令来编译 C++ 程序。这就够了。

那么如何运行成功编译的 C 或 C++ 程序并查看结果呢?我们将在下一章详细探讨这一点。