通常所說的GCC是GUN Compiler Collection的簡稱,除了編譯程序之外,它還含其他相關(guān)工具,所以它能把易于人類使用的高級(jí)語言編寫的源代碼構(gòu)建成計(jì)算機(jī)能夠直接執(zhí)行的二進(jìn)制代碼。GCC是linux平臺(tái)下最常用的編譯程序,它是Linux平臺(tái)編譯器的事實(shí)標(biāo)準(zhǔn)。同時(shí),在Linux平臺(tái)下的嵌入式開發(fā)領(lǐng)域,GCC也是用得最普遍的一種編譯器。GCC之所以被廣泛采用,是因?yàn)樗苤С指鞣N不同的目標(biāo)體系結(jié)構(gòu)。例如,它既支持基于宿主的開發(fā)(簡單講就是要為某平臺(tái)編譯程序,就在該平臺(tái)上編譯),也支持交叉編譯(即在A平臺(tái)上編譯的程序是供平臺(tái)B使用的)。目前,GCC支持的體系結(jié)構(gòu)有四十余種,常見的有X86系列、Arm、PowerPC等。同時(shí),GCC還能運(yùn)行在不同的操作系統(tǒng)上,如Linux、Solaris、Windows等。
除了上面講的之外,GCC除了支持C語言,還支持多種其他語言,例如C++、Ada、java、Objective-C、FORTRAN、Pascal、go等。
GCC的安裝:
Ubuntu等基于Debian發(fā)行版Linux可以使用如下命令安裝:
apt -get install gcc
Fedora等基于RPM發(fā)行版Linux可以使用如下命令安裝:
yum install gcc
使用如下命令查看gcc的版本:
gcc --version
本文地址:http://www.CUOXin.com/archimedes/p/linux-gcc.html,轉(zhuǎn)載請(qǐng)注明源地址。
二、程序的編譯過程對(duì)于GUN編譯器來說,程序的編譯要經(jīng)歷預(yù)處理、編譯、匯編、連接四個(gè)階段,如下圖所示:
從功能上分,預(yù)處理、編譯、匯編是三個(gè)不同的階段,但GCC的實(shí)際操作上,它可以把這三個(gè)步驟合并為一個(gè)步驟來執(zhí)行。下面以C語言為例來談一下不同階段的輸入和輸出情況。
GCC編譯器的基本選項(xiàng)如下表:
類型 | 說明 |
-E | 預(yù)處理后即停止,不進(jìn)行編譯、匯編及連接 |
-S | 編譯后即停止,不進(jìn)行匯編及連接 |
-c | 編譯或匯編源文件,但不進(jìn)行連接 |
-o file | 指定輸出文件file |
在預(yù)處理階段,輸入的是C語言的源文件,通常為*.c。它們通常帶有.h之類頭文件的包含文件。這個(gè)階段主要處理源文件中的#ifdef、 #include和#define命令。該階段會(huì)生成一個(gè)中間文件*.i,但實(shí)際工作中通常不用專門生成這種文件,因?yàn)榛旧嫌貌坏?;若非要生成這種文件不可,可以利用下面的示例命令:
gcc -E test.c -o test.i
在編譯階段,輸入的是中間文件*.i,編譯后生成匯編語言文件*.s 。這個(gè)階段對(duì)應(yīng)的GCC命令如下所示:
gcc -S test.i -o test.s
在匯編階段,將輸入的匯編文件*.s轉(zhuǎn)換成機(jī)器語言*.o。這個(gè)階段對(duì)應(yīng)的GCC命令如下所示:
gcc -c test.s -o test.o
最后,在連接階段將輸入的機(jī)器代碼文件*.s(與其它的機(jī)器代碼文件和庫文件)匯集成一個(gè)可執(zhí)行的二進(jìn)制代碼文件。這一步驟,可以利用下面的示例命令完成:
gcc test.o -o test
運(yùn)行如下:
可以通過:cat -n [filename]命令查看每一個(gè)階段的文件內(nèi)容
上面介紹了GCC編譯過程的四個(gè)階段以及相應(yīng)的命令。下面我們進(jìn)一步介紹常用的GCC的模式。
三、警告選項(xiàng)GCC提供了大量的警告選項(xiàng),對(duì)代碼中可能存在的問題提出警告,通??梢允褂?Wall來開啟以下警告
GCC的編譯器警告選項(xiàng)如下表:
類型 | 說明 |
-Wall | 啟用所有警告信息 |
-Werror | 在發(fā)生警告時(shí)取消編譯操作,即將警告看作是錯(cuò)誤 |
-w | 禁用所有警告信息 |
實(shí)例1:給出一段代碼,使用gcc進(jìn)行編譯,同時(shí)開啟警告信息(test1.c)
#include<stdio.h>int main(){ int i; for(i = 0; i <= 3; i++) PRintf("hello gcc!/n"); //return 0;}
使用-Wall開啟警告:
從上面可以看出,GCC給出了警告信息,意思是main函數(shù)的返回值被聲明為int,但是沒有返回值,GCC并不是簡單的發(fā)出警告,會(huì)中斷整個(gè)編譯過程
如果不想看到警告信息,可以使用-w來禁止所有的警告。
此外,GCC還提供了許多以-W開頭的選項(xiàng),允許用戶指定輸出某個(gè)特定的警告,例如:
-Wcomment:出現(xiàn)注釋嵌套時(shí)發(fā)出警告。
-Wconversion:如果程序中存在隱式類型轉(zhuǎn)換,則發(fā)出警告。
-Wformat:檢查printf和scanf等格式化輸入輸出函數(shù)的格式字符串和參數(shù)類型的匹配情況,如果發(fā)現(xiàn)不匹配則發(fā)出警告。
-Winline:如果函數(shù)不能被內(nèi)聯(lián),則發(fā)出警告。
-Wlong-long:如果使用了long long型數(shù)據(jù),則發(fā)出警告。
-Wmain:如果main函數(shù)的返回類型不是int型,或者調(diào)用main函數(shù)時(shí)使用的參數(shù)數(shù)目不正確,則發(fā)出警告。
-Wmissing-declarations:如果定義了全局函數(shù),但卻沒有在頭文件中聲明,則發(fā)出警告。
-Wparentheses:在某些情況下,如果忽略掉了括號(hào),則會(huì)發(fā)出警告。
-Wreturn-type:如果函數(shù)定義了返回類型,而默認(rèn)類型是int型,編譯器會(huì)發(fā)出警告。
-Wuninitialized:如果使用的自動(dòng)變量沒有被初始化,則發(fā)出警告。
-Wundef:如果在#if宏中使用了未定義的變量做判斷,則發(fā)出警告。
-Wunused:如果聲明的變量或static型函數(shù)沒有使用,則發(fā)出警告。
實(shí)例2:給出一段代碼,使用gcc進(jìn)行編譯,同時(shí)開啟警告信息(test2.c)
#include<stdio.h>int main( ){ int a = 1; int b = 0; int c = 1; if(a && b || c) { ; } if(a == 1) if(b == 1) printf("b = 1/n"); else printf("b != 1/n"); return 0;}
使用-Wparentheses開啟警告:
GCC具有優(yōu)化代碼的功能,主要的優(yōu)化選項(xiàng)包括如下:
一般來說,優(yōu)化級(jí)別越高,生成可執(zhí)行文件的運(yùn)行速度也越快,但消耗在編譯上的時(shí)間就越長,因此在開發(fā)的時(shí)候最好不要使用優(yōu)化選項(xiàng),到軟件發(fā)行或開發(fā)結(jié)束的時(shí)候才考慮對(duì)最終生成的代碼進(jìn)行優(yōu)化。
實(shí)例:給出一段代碼,使用gcc進(jìn)行編譯,同時(shí)比較優(yōu)化前后執(zhí)行程序所花的時(shí)間(test3.c)
#include<stdio.h>int main(){ int i, j, x; x = 0; for(i = 0; i < 100000; i++) { for(j = i; j > 0; j--) { x += j; } } return 0;}
運(yùn)行后的結(jié)果如下:
可以看到,優(yōu)化的效果十分的顯著
新聞熱點(diǎn)
疑難解答
圖片精選