天天看點

GNU gcc 和 g++ 的差別詳解

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

誤區一: gcc 隻能編譯 C 代碼,g++ 隻能編譯 C++ 代碼

兩者都可以,但是請注意:

1. 字尾為 .c 的,gcc 把它當作是 C 程式,而 g++ 當作是 C++ 程式;

    字尾為.cpp的,兩者都會認為是 C++程式;

    注意: 雖然 C++ 是 C 的超集,但是兩者對文法的要求是有差別的! C++ 的文法規則更加嚴謹一些。

    例如:

​<code>​#include &lt;stdio.h&gt; ​</code>​​<code>​int main( int   argc,           char *argv[] ) {    if (​</code>​ ​<code>​0​</code>​ ​<code>​==​</code>​ ​<code>​argv )     {         return;     }    printString( argv );    return; }​</code>​

​<code>​ int printString( char* string ) {   sprintf( string,             "This is a test.n" ); } ​</code>​

如果按照 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 &lt;iostream&gt;

#include "test.h"

using namespace std;

void

CppPrintf( void )

{

  cout &lt;&lt; "Hellon";

}

main.cpp:

#include &lt;stdlib.h&gt;

#include &lt;stdio.h&gt;

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  &lt;-- 注意此函數的命名

.type  CppPrintf, @function

$ gcc -S test.cpp

完全相同!

2. 去掉 test.h 裡 void CppPrintf(void); 前面的 extern "C",看用 gcc 和 g++ 命名有什麼不同。

​<code>​$​</code>​ ​<code>​g++ -S test.cpp ​</code>​​<code>​$​</code>​ ​<code>​less test.s .globl  _Z9CppPrintfv ​</code>​ &lt;-- 注意此函數的命名

​<code>​.type  _Z9CppPrintfv, @function ​</code>​

​<code>​$ gcc -S test.cpp $ less test.s .globl  _Z9CppPrintfv​</code>​ &lt;-- 注意此函數的命名​

<code>​ .type  _Z9CppPrintfv, @function ​</code>​​<code>​完全相同!​</code>​

結論:

完全相同,可見 extern "C" 與采用 gcc 或 g++ 并無關系,

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

繼續閱讀