gcc和g++是什麼,有什麼區別?

2021-02-19 良許Linux

素材來源:C語言中文網

編輯整理:strongerHuang

目前(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(){    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: 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> 頭文件提供的 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()'
#省略了諸多錯誤信息

讀者可自行編譯,就可以看到很多報錯信息。其根本原因就在於,該程序中使用了標準庫 <iostream> 和<string> 提供的類對象,而 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++ 指令,這就足夠了。

添加良許個人微信即送3套程式設計師必讀資料

→ 精選技術資料共享

→ 高手如雲交流社群

本公眾號全部博文已整理成一個目錄,請在公眾號裡回復「m」獲取!

推薦閱讀:

GitHub 標星 3w+,很全面的算法和數據結構知識

C++雖不會過時,但是真的難啊!

手機沒網了,卻還能支付,這是什麼原理?

5T技術資源大放送!包括但不限於:C/C++,Linux,Python,Java,PHP,人工智慧,單片機,樹莓派,等等。在公眾號內回復「1024」,即可免費獲取!!

相關焦點

  • gcc和g++有什麼區別?
    需要強調的一點是,這並不是 gcc 和 g++ 的區別,gcc 指令也可以用來編譯 C++ 程序,同樣 g++ 指令也可以用於編譯 C 語言程序。實際上,只要是 GCC 支持編譯的程序代碼,都可以使用 gcc 命令完成編譯。
  • 編譯C語言程序,使用 gcc 指令,而C++程序則推薦使用 g++指令!
    需要強調的一點是,這並不是 gcc 和 g++ 的區別,gcc 指令也可以用來編譯 C++ 程序,同樣 g++ 指令也可以用於編譯 C 語言程序。那麼,gcc 和 g++ 的區別是什麼呢?接下來就給讀者做詳細的講解。實際上,只要是 GCC 支持編譯的程序代碼,都可以使用 gcc 命令完成編譯。
  • linux下Clang和gcc的區別
    內置有靜態分析工具,可以對代碼進行靜態分析 (clang—analyze) 。這也是 gcc 做不到的 。專注,因為 clang 只需要完成詞法和語法分析,代碼優化和機器代碼的生成工作由 llvm 完成。所以和全部由自己包下的 gcc 比起來, clang 可以更專注地做好一件事。
  • GCC寫個庫給你玩,就這?
    -vgcc --versiong++ -vg++ --versiongcc和g++的區別gcc和g++ 都是GNU (組織)的一個編譯器。,C++的語法規則更加嚴謹一些編譯階段,g++會調用gcc, 對於C++代碼,兩者是等價的,但是因為gcc命令不能自動和C++程序使用的庫聯接,所以通常用g++來完成連結,為了統一起見,乾脆編譯/連結統統用g++了 ,這就給人一種錯覺,好像 cpp 程序只能用 g++ 似的.
  • 編譯器 GCC 和 Clang 有什麼區別?
    今天就來談談Clang和GCC的異同。網址:http://gcc.gnu.org/GCC:GNU(Gnu's Not Unix)編譯器套裝(GNU Compiler Collection,GCC),指一套程式語言編譯器,以GPL及LGPL許可證所發行的自由軟體,也是GNU項目的關鍵部分,也是GNU工具鏈的主要組成部分之一。
  • GCC編譯基礎
    ❝在gcc中,如果指定-shared不指定-fPIC會報錯,無法生成非PIC的動態庫,不過clang可以。❞庫中函數和變量的地址是相對地址,不是絕對地址,真實地址在調用動態庫的程序加載時形成。動態庫的名稱有別名(soname),真名(realname)和連結名(linker name)。
  • GNU/GCC 基礎介紹
    2   什麼是GCC?包括gcc,g ++,ar,as,ld,objcopy,objdump等。不同的平臺都有一套完整的工具。否則就是gcc嵌入式(MIPS):mips-linux-gnu-。彙編器和連結器。
  • 如何在Ubuntu 18.04上安裝GCC編譯器
    鍵入以下命令安裝所需的GCC和G ++版本:linuxidc@linuxidc:~/www.linuxidc.com$  sudo apt install gcc-7 g++-7 gcc-8 g++-8 gcc
  • 在Ubuntu中安裝gcc
    gcc是一個開源免費的編譯器,功能強大,性能穩定,已被眾多的商業公司(Microchip, ST...)的 IDE作為默認的編譯器。
  • gcc、arm-linux-gcc和arm-elf-gcc的關係?
    \n"); return 0;}編譯命令為: gcc -o test test.c 編譯生成 test 可執行文件。gcc 編譯流程分為四個步驟:預處理、編譯 、彙編、連結。個人認為預處理和編譯主要由 gcc-core 來完成,彙編和連結主要由 Binutils 來完成。
  • 3分鐘看懂gcc、arm-Linux-gcc和arm-elf-gcc的組成及區別
    GCC 內部結構主要由 Binutils、gcc-core、Glibc 等軟體包組成。1. Binutils:它是一組開發工具,包括連接器,彙編器和其他用於目標文件和檔案的工具。關於 Binutils 的介紹可以參考 Binutils 簡單介紹。這個軟體包依賴於不同的目標機的平臺。
  • gcc中 -pthread和 -lpthread的區別
    $ gcc -v -pthread -c x.c  ...  $ gcc -v x.o -ox -pthread  /usr/lib/gcc/i486-linux-gnu/4.2.4/collect2 --eh-frame-hdr -m elf_i386 --hash-style=both  -dynamic-linker /lib/ld-linux.so.2 -ox  /usr/lib/gcc/i486
  • Debug模式和Release模式有什麼區別?
    tips:上述優化選項如果想要了解具體含義可以看https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html 官方文檔。編譯器有這麼多優化級別,Debug版本和Release版本其實就是優化級別的區別,Debug稱為調試版本,編譯的結果通常包含有調試信息,沒有做任何優化,方便開發人員進行調試,Release稱為發布版本,不會攜帶調試信息,同時編譯器對代碼進行了很多優化,使代碼更小,速度更快,發布給用戶使用,給用戶使用以更好的體驗。但Release模式編譯比Debug模式花的時間也會更多。
  • Linux下非root用戶GCC編譯器安裝 !
    下面幾個庫在安裝以後也是記得添加環境變量和source,或者也可以一次性把所有環境變量都添加和source以後再安裝,這樣的好處是避免了遺漏了某一個庫導致接下來的庫安裝時報錯。gcc \CXX=/usr/bin/g++ \.
  • 報關和清關有什麼區別?清關費和報關費有什麼區別?
    報關和清關有什麼區別?
  • 什麼是Docker,和虛擬機有怎樣的區別
    大家好今天是母親節了,大家早上有沒有給母親發一個簡訊或者打個電話呢,如果看到了今天推送的文章,記得晚上下班後給母親發個祝福,聊聊家常……
  • gcc&arm-linux-gcc編譯過程詳解
    老規矩,文字無法完整描述視頻內容,如果覺得這些文章對你有用,想進一步學習更深層次的乾貨,請訪問100ask.taobao.com購買arm裸機1期加強版視頻課程。第1節_gcc編譯器1_常用選項_編譯過程詳解gcc的使用方法gcc [選項] 文件名gcc常用選項 一個c/c++文件要經過預處理、編譯、彙編和連結才能變成可執行文件。
  • docx和doc有什麼區別
    docx格式與doc格式都是word文本格式,但是二者的差距實際上是很大的,docx和doc的區別顯著的一點就是體積大小的不同。
  • /arm-none-linux-gnueabi-gcc: No such file or directory
    arm-none-linux-gnueabi-nmarm-none-linux-gnueabi-c++ arm-none-linux-gnueabi-objcopyarm-none-linux-gnueabi-c++filt arm-none-linux-gnueabi-objdumparm-none-linux-gnueabi-cpp arm-none-linux-gnueabi-ranlibarm-none-linux-gnueabi-g++
  • job 和 work有什麼區別?
    job 和 work的區別是什麼?被「炒魷魚」除了 fire還能怎麼說?