不經(jīng)意間,GCC已發(fā)展到了4.3的版本,盡管在軟件開(kāi)發(fā)社區(qū)之外乏人聞問(wèn),但因?yàn)镚CC在幾乎所有開(kāi)源軟件和自由軟件中都會(huì)用到,因此它的編譯性能的漲 落會(huì)直接影響到Linux 、Firefox 乃至于OpenOffice.org和Apache等幾千個(gè)項(xiàng)目的開(kāi)發(fā)。因此,把GCC擺在開(kāi)源軟件的核心地位是一點(diǎn)也不為過(guò)。另一方面,GCC4.3的 出現(xiàn),正在牽引著廣大程序員們的心。如果我們非要用一個(gè)詞來(lái)說(shuō)明GCC與程序員之間的關(guān)系,那無(wú)疑是"心隨心動(dòng)"。
歷史篇
作為自由軟件的旗艦項(xiàng)目,Richard Stallman 在十多年前剛開(kāi)始寫(xiě)作 GCC 的時(shí)候,還只是把它當(dāng)作僅僅一個(gè) C 程序語(yǔ)言的編譯器;GCC 的意思也只是 GNU C Compiler 而已。經(jīng)過(guò)了這么多年 的發(fā)展,GCC 已經(jīng)不僅僅能支持 C 語(yǔ)言;它現(xiàn)在還支持Ada 語(yǔ)言、C++ 語(yǔ)言、Java 語(yǔ)言、Objective C 語(yǔ)言、Pascal 語(yǔ)言、COBOL語(yǔ)言,以及支持函數(shù)式編程和邏輯編程的 Mercury 語(yǔ)言,等等。而 GCC 也不再單只是 GNU C 語(yǔ)言編譯器的意思了,而是變成了 GNU Compiler Collection 也即是 GNU 編譯器家族的意思了。另一方面,說(shuō)到 GCC 對(duì)于各種硬件平臺(tái)的支持,概括起來(lái)就是一句話:無(wú)所不在。幾乎所有有點(diǎn)實(shí)際用途的硬件平臺(tái),甚至包括有些不那么有實(shí)際用途的硬件平臺(tái)。
Gcc 簡(jiǎn)介
Linux系統(tǒng)下的gcc(GNU C Compiler)是GNU推出的功能強(qiáng)大、性能優(yōu)越的多平臺(tái)編譯器,是GNU的代表作品之一。Gcc是可以在多種硬體平臺(tái)上編譯出可執(zhí)行程序的超級(jí)編譯器,其執(zhí)行效率與一般的編譯器相比平均效率要高20%~30%。
官方網(wǎng)站:
http://gcc.gnu.org/
gcc是linux的唯一編譯器,沒(méi)有g(shù)cc就沒(méi)有l(wèi)inux,gcc的重要性就不可言喻啦。居然這么重要,那就很值得我們來(lái)好好研究下啦。好啦,開(kāi)始我們的gcc之旅吧!
首先消除gcc和g++誤區(qū)吧。
gcc和g++都是GNU(組織)的一個(gè)編譯器。
誤區(qū)一:gcc只能編譯c代碼,g++只能編譯c++代碼
兩者都可以,但是請(qǐng)注意:
1.后綴為.c的,gcc把它當(dāng)作是C程序,而g++當(dāng)作是c++程序;后綴為.cpp的,兩者都會(huì)認(rèn)為是c++程序,注意,雖然c++是c的超集,但是兩者對(duì)語(yǔ)法的要求是有區(qū)別的,例如:
#include <stdio.h>
int main(int argc, char* argv[]) {
if(argv == 0) return;
printString(argv);
return;
}
int printString(char* string) {
sprintf(string, "This is a test."n");
}
如果按照C的語(yǔ)法規(guī)則,OK,沒(méi)問(wèn)題,但是,一旦把后綴改為cpp,立刻報(bào)三個(gè)錯(cuò):“printString未定義”;
“cannot convert `char**' to `char*”;
”return-statement with no value“;
分別對(duì)應(yīng)前面紅色標(biāo)注的部分。可見(jiàn)C++的語(yǔ)法規(guī)則更加嚴(yán)謹(jǐn)一些。
2.編譯階段,g++會(huì)調(diào)用gcc,對(duì)于c++代碼,兩者是等價(jià)的,但是因?yàn)間cc命令不能自動(dòng)和C++程序使用的庫(kù)聯(lián)接,所以通常用g++來(lái)完成鏈接,為了統(tǒng)一起見(jiàn),干脆編譯/鏈接統(tǒng)統(tǒng)用g++了,這就給人一種錯(cuò)覺(jué),好像cpp程序只能用g++似的。
誤區(qū)二:gcc不會(huì)定義__cplusplus宏,而g++會(huì)
實(shí)際上,這個(gè)宏只是標(biāo)志著編譯器將會(huì)把代碼按C還是C++語(yǔ)法來(lái)解釋,如上所述,如果后綴為.c,并且采用gcc編譯器,則該宏就是未定義的,否則,就是已定義。
誤區(qū)三:編譯只能用gcc,鏈接只能用g++
嚴(yán)格來(lái)說(shuō),這句話不算錯(cuò)誤,但是它混淆了概念,應(yīng)該這樣說(shuō):編譯可以用gcc/g++,而鏈接可以用g++或者gcc -lstdc++。因?yàn)間cc命令不能自動(dòng)和C++程序使用的庫(kù)聯(lián)接,所以通常使用g++來(lái)完成聯(lián)接。但在編譯階段,g++會(huì)自動(dòng)調(diào)用gcc,二者等價(jià)。
誤區(qū)四:extern "C"與gcc/g++有關(guān)系
實(shí)際上并無(wú)關(guān)系,無(wú)論是gcc還是g++,用extern "c"時(shí),都是以C的命名方式來(lái)為symbol命名,否則,都以c++方式命名。試驗(yàn)如下:
me.h:
extern "C" void CppPrintf(void);
me.cpp:
#include <iostream>
#include "me.h"
using namespace std;
void CppPrintf(void)
{
cout << "Hello"n";
}
test.cpp:
#include <stdlib.h>
#include <stdio.h>
#include "me.h"
int main(void)
{
CppPrintf();
return 0;
}
1. 先給me.h加上extern "C",看用gcc和g++命名有什么不同
[root@root G++]# g++ -S me.cpp
[root@root G++]# less me.s
.globl _Z9CppPrintfv //注意此函數(shù)的命名
.type CppPrintf, @function
[root@root GCC]# gcc -S me.cpp
[root@root GCC]# less me.s
.globl _Z9CppPrintfv //注意此函數(shù)的命名
.type CppPrintf, @function
完全相同!
2. 去掉me.h中extern "C",看用gcc和g++命名有什么不同
[root@root GCC]# gcc -S me.cpp
[root@root GCC]# less me.s
.globl _Z9CppPrintfv //注意此函數(shù)的命名
.type _Z9CppPrintfv, @function
[root@root G++]# g++ -S me.cpp
[root@root G++]# less me.s
.globl _Z9CppPrintfv //注意此函數(shù)的命名
.type _Z9CppPrintfv, @function
完全相同!