1. 程式人生 > >GNU gcc 和 g++ 的區別詳解

GNU gcc 和 g++ 的區別詳解

gcc 和 g++ 都是 GNU 組織的編譯器。

誤區一: gcc 只能編譯 C 程式碼,g++ 只能編譯 C++ 程式碼
兩者都可以,但是請注意:
1. 字尾為 .c 的,gcc 把它當作是 C 程式,而 g++ 當作是 C++ 程式;
 字尾為.cpp的,兩者都會認為是 C++程式;
 注意: 雖然 C++ 是 C 的超集,但是兩者對語法的要求是有區別的! C++ 的語法規則更加嚴謹一些。
 例如:
#include <stdio.h>
int
main( int   argc,
          char *argv[] )
{
   if (
0==argv )
    {
        return;

    }
   printString( argv );
   return;
}


int
printStringchar* string )
{
  sprintf( string,
            "This is a test.n" );
}

如果按照 C 的語法規則,OK,沒問題,但是,一旦把字尾改為 .cpp,立刻報三個錯:
“printString未定義”;
“cannot convert `char**' to `char*”;
“return-statement with no value”;
可見C++的語法規則更加嚴謹一些。


2. 編譯階段,g++ 會呼叫 gcc,對於 C++ 程式碼,兩者是等價的,

 但是因為 gcc 命令不能自動和 C++ 庫連結,所以通常用 g++ 來完成連結,
 為了統一,乾脆編譯與連結統統用 g++ 了,就給人一種錯覺,好像 cpp 程式只能用 g++ 似的。

誤區二: gcc 不會定義 __cplusplus 巨集,而 g++ 會
實際上,這個巨集只是標誌著編譯器將會把程式碼按 C 還是 C++ 語法來解釋,
如上所述,如果字尾為 .c,並且採用 gcc 編譯器,則該巨集就是未定義的,否則,就是已定義。

誤區三: 編譯只能用 gcc,連結只能用 g++
嚴格來說,這句話不算錯誤,但是它混淆了概念,應該這樣說:
編譯可以用 gcc 或 g++,而連結可以用 g++ 或者 gcc -lstdc++。

因為 gcc 命令不能自動和 C++ 庫連結,所以通常使用 g++ 來完成連結。
但在編譯階段,g++ 會自動呼叫 gcc,二者等價。

誤區四: extern "C" 與 gcc 或 g++ 有關係
實際上並無關係,
無論是 gcc 還是 g++,用 extern "c" 時,都是以 C 的命名方式來為 函式 命名,
否則,都以 C++ 方式為 函式 命名。
試驗如下:
test.h:
extern "C" void CppPrintf(void);

test.cpp:
#include <iostream>
#include "test.h"
using namespace std;
void
CppPrintf( void )
{
  cout << "Hellon";
}

main.cpp:
#include <stdlib.h>
#include <stdio.h>
#include "test.h"
int
main( void )
{
 CppPrintf();
 return 0;
}

1. 先給 test.h 裡的 void CppPrintf(void); 加上 extern "C",看用 gcc 和 g++ 命名有什麼不同。
$ g++ -S test.cpp
$ less test.s
.globl CppPrintf <-- 注意此函式的命名
.type  CppPrintf, @function

$ gcc -S test.cpp
$ less test.s
.globl CppPrintf <-- 注意此函式的命名
.type CppPrintf, @function
完全相同!


2. 去掉 test.h 裡 void CppPrintf(void); 前面的 extern "C",看用 gcc 和 g++ 命名有什麼不同。
$g++ -S test.cpp
$less test.s
.globl  _Z9CppPrintfv 
 <-- 注意此函式的命名
.type  _Z9CppPrintfv, @function

$ gcc -S test.cpp
$ less test.s
.globl  _Z9CppPrintfv
 <-- 注意此函式的命名
.type  _Z9CppPrintfv, @function
完全相同!

結論:
完全相同,可見 extern "C" 與採用 gcc 或 g++ 並無關係,

以上的試驗還間接的印證了前面的說法:在編譯階段,g++ 是呼叫 gcc 的。

補充:gcc和g++在程式設計的時候平時覺的區別就是結構體的定義

對了,當我使用GCC編譯的時候,編譯器返回的錯誤是在我的結構體設計的部分。
typedef struct NodeTrie
{ 
    NodeTrie *p;

    ……;

}
總是會說我的第二個NodeTrie是沒有定義的,但是使用了G++之後,問題解決。

按照c的寫法 第二個NodeTrie *p應當寫成struct NodeTrie *p,按照c++的寫法實際不需要typedef了,struct與class的唯一區別就是成員變數前者預設public後者預設private 。
c的語法在NodeTrie *p這個時候 由於還沒走到右花括號那個NodeTrie ,也就是說typedef還沒有完成,那麼自然他不認識NodeTrie 這是什麼東西,只認識struct NodeTrie