目前(2020-09)GCC 编译器已经更新至 10.2版本,其功能也由最初仅能编译 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 语言,因此对于 C 语言程序来说,使用 gcc 编译还是使用 g++ 编译,应该没有什么区别,事实并非如此。严格来说,C++ 标准和 C 语言标准的语法要求是有区别的。举个例子:

//位于 demo.c 文件中
#include <stdio.h>
int main() {
constchar * 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: In function ‘int main()’:
demo.c:5: error: ‘printStr’ was not declared in this scope
demo.c:6: error: return-statement with no value, in function returning ‘int’
[root@bogon ~]#

可以看到,GCC 编译器发现了 3 处错误。显然,C++ 标准对代码书写规范的要求更加严格。

除此之外对于编译执行 C++ 程序,使用 gcc 和 g++ 也是有区别的。要知道,很多 C++ 程序都会调用某些标准库中现有的函数或者类对象,而单纯的 gcc 命令是无法自动链接这些标准库文件的。举个例子:

//demo.cpp
#include <iostream>
#include <string>
using namespace std; int main()
{
string str = "C语言中文网";
cout << str << endl;
return 0;
}

这是一段很简单的 C++ 程序,其通过 头文件提供的 string 字符串类定义了一个字符串对象,随后使用 cout 输出流对象将其输出。对于这段 C++ 代码,如果我们使用 g++ 指令编译,如下所示:

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

可以看到,整个编译过程没有报任何错误。但如果使用 gcc 指令:

[root@bogon ~]# gcc demo.cpp
/tmp/ccIOnwra.o: In function `main':
demo.cpp:(.text+0x13): undefined reference to `std::allocator<char>::allocator()'
#省略了诸多错误信息

读者可自行编译,就可以看到很多报错信息。其根本原因就在于,该程序中使用了标准库 和 提供的类对象,而 gcc 默认是无法找到它们的。

如果想使用 gcc 指令来编译执行 C++ 程序,需要在使用 gcc 指令时,手动为其添加 -lstdc++ -shared-libgcc 选项,表示 gcc 在编译 C++ 程序时可以链接必要的 C++ 标准库。也就是说,我们可以这样编译 demo.cpp 文件:

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

由此,demo.cpp 就被成功的编译了。

读者可以这样认为,g++ 指令就等同于gcc -xc++ -lstdc++ -shared-libgcc指令。显然后者书写是非常麻烦的,大多数人会更喜欢前者。

对于 gcc 和 g++ 指令,还有其它更多细节方面的区别,这里不再做更多的赘述。读完本节,读者只需要知道,对于 C 语言程序的编译,我们应该使用 gcc 指令,而编译 C++ 程序则推荐使用 g++ 指令,这就足够了。

【知识点】 gcc和g++的联系和区别的更多相关文章

  1. 【编程基础】编译器 cc、gcc、g++、CC 的区别

    参考 1. 编译器 cc.gcc.g++.CC 的区别; 完

  2. cc、gcc、g++、CC的区别和联系

    gcc是C编译器:g++是C++编译器:linux下cc一般是一个符号连接,指向gcc:gcc和g++都是GUN(组织)的编译器.而CC则一般是makefile里面的一个名字,即宏定义,嘿,因为Lin ...

  3. cc、gcc、g++、CC的区别概括

    gcc是C编译器:g++是C++编译器:linux下cc一般是一个符号连接,指向gcc:gcc和g++都是GUN(组织)的编译器.而CC则一般是makefile里面的一个名字,即宏定义,嘿,因为Lin ...

  4. 转载 cc、gcc、g++、CC的区别概括

    gcc是C编译器:g++是C++编译器:linux下cc一般是一个符号连接,指向gcc:gcc和g++都是GUN(组织)的编译器.而CC则一般是makefile里面的一个名字,即宏定义,嘿,因为Lin ...

  5. 编译器 cc、gcc、g++、CC 的区别

    gcc 是GNU Compiler Collection,原名为Gun C语言编译器,因为它原本只能处理C语言,但gcc很快地扩展,包含很多编译器(C.C++.Objective-C.Ada.Fort ...

  6. GCC与G++那些事儿

    StackOverflow上一个很有名的问题,gcc和g++到底有什么区别? 答案如下: GCC: GNU Compiler Collection 指的是GNU编译器所支持的所有不同的类型的语言 gc ...

  7. GCC的gcc和g++区别

    看的Linux公社的一篇文章,觉得不错,内容复制过来了. 其实在这之前,我一直以为gcc和g++是一个东西,只是有两个不同的名字而已,今天在linux下编译一个c代码时出现了错误才找了一下gcc和g+ ...

  8. gcc 和g++区别

    gcc和g++都是GNU的一个编译器;这两者的区别:1.从源文件上看,对于文件后缀(扩展名)为.c的test.c文件,gcc会把它看成是C程序,而g++则会把它看成是C++程序;而对于文件后缀(扩展名 ...

  9. Linux - gcc和g++的区别

    一般linux系统都自带了gcc编译器的,你可以用你的安装光盘去安装,如果你是觉得自带的gcc版本太低了,可以去gcc的官方网站可以下载到,编译需要很长的时间,如果你只编译C或者C++可以只下载gcc ...

随机推荐

  1. python爬取QQVIP音乐

    QQ音乐相比于网易云音乐加密部分基本上没有,但是就是QQ音乐的页面与页面之间的联系太强了,,导致下载一个音乐需要分析前面多个页面,找数据..太繁琐了 1.爬取链接:https://y.qq.com/ ...

  2. Vue的七种传值方式

    目录 1,父传子 2,子传父 3,兄弟组件传值 4,父组件使用子组件的数据和方法 5,子组件使用父组件的数据和方法 6,Vuex传值 6.1,定义store 6.2,挂载 6.3,使用 7,路由传值 ...

  3. OpenStack Train版-10.安装neutron网络服务(网络节点:可选)

    可选:安装neutron网络服务节点(neutron01网络节点192.168.0.30)网络配置按照官网文档的租户自助网络 配置系统参数 echo 'net.ipv4.ip_forward = 1' ...

  4. Linux自带神器logrotate详解

    Linux自带神器logrotate详解 散尽浮华 运维 3天前   作者:散尽浮华 链接:https://www.cnblogs.com/kevingrace/p/6307298.html 对于 L ...

  5. C++的memset

    1. 需要的头文件 C中为<memory.h> 或 <string.h> C++中为<cstring> void * memset ( void * ptr, in ...

  6. set CSS style in js solutions All In One

    set CSS style in js solutions All In One css in js set each style property separately See the Pen se ...

  7. array group by key javascript

    array group by key javascript calendar Array.reduce https://developer.mozilla.org/en-US/docs/Web/Jav ...

  8. auto skip function args

    auto skip function args https://repl.it/@xgqfrms/auto-skip-function-args "use strict"; /** ...

  9. SameSite & Cookies

    SameSite & Cookies SameSite=None && Secure (HTTPS) https://developer.mozilla.org/en-US/d ...

  10. 算法型稳定币USDN有哪些使用功能

    众所周知,稳定币是基于区块链的支付工具,旨在实现最终用户要求的价格稳定性.有些稳定币利用法定货币作为抵押资产.其他则使用一系列其他非法定类型的抵押资产.还有一些尝试使用算法来实现价格稳定性而根本没有抵 ...