編譯器GCC與Clang的異同

fengbingchun發表於2018-02-04

GCC:GNU(Gnu's Not Unix)編譯器套裝(GNU Compiler Collection,GCC),指一套程式語言編譯器,以GPL及LGPL許可證所發行的自由軟體,也是GNU專案的關鍵部分,也是GNU工具鏈的主要組成部分之一。GCC(特別是其中的C語言編譯器)也常被認為是跨平臺編譯器的事實標準。1985年由理查德·馬修·斯托曼開始發展,現在由自由軟體基金會負責維護工作。GCC原本用C開發,後來因為LLVM、Clang的崛起,它更快地將開發語言轉換為C++。

GCC支援的語言:原名為GNU C語言編譯器(GNU C Compiler),因為它原本只能處理C語言。GCC在釋出後很快地得到擴充套件,變得可處理C++。之後也變得可處理Fortran、Pascal、Objective-C、Java、Ada,Go與其他語言。

許多作業系統,包括許多類Unix系統,如Linux及BSD家族都採用GCC作為標準編譯器。蘋果電腦預裝的Mac OS X作業系統也採用這個編譯器。

GCC目前由世界各地不同的數個程式設計師小組維護。它是移植到最多中央處理器架構以及最多作業系統的編譯器。由於GCC已成為GNU系統的官方編譯器(包括GNU/Linux家族),它也成為編譯與建立其他作業系統的主要編譯器,包括BSD家族、Mac OS X、NeXTSTEP與BeOS。

GCC通常是跨平臺軟體的編譯器首選。有別於一般侷限於特定系統與執行環境的編譯器,GCC在所有平臺上都使用同一個前端處理程式,產生一樣的中介碼,因此此中介碼在各個其他平臺上使用GCC編譯,有很大的機會可得到正確無誤的輸出程式。

GCC支援的主要處理器架構:ARM、x86、x86-64、MIPS、PowerPC等。

        GCC結構:GCC的外部介面長得像一個標準的Unix編譯器。使用者在命令列下鍵入gcc之程式名,以及一些命令引數,以便決定每個輸入檔案使用的個別語言編譯器,併為輸出程式碼使用適合此硬體平臺的組合語言編譯器,並且選擇性地執行聯結器以製造可執行的程式。每個語言編譯器都是獨立程式,此程式可處理輸入的原始碼,並輸出組合語言碼。全部的語言編譯器都擁有共通的中介架構:一個前端解析匹配此語言的原始碼,併產生一抽象語法樹,以及一翻譯此語法樹成為GCC的暫存器轉換語言的後端。編譯器最優化與靜態程式碼解析技術在此階段應用於程式碼上。最後,適用於此硬體架構的組合語言程式碼以傑克·戴維森與克里斯·弗雷澤發明的演算法產出。

幾乎全部的GCC都由C/C++寫成,除了Ada前端大部分以Ada寫成。

        Clang:是一個C、C++、Objective-C和Objective-C++程式語言的編譯器前端。它採用了底層虛擬機器(LLVM)作為其後端。它的目標是提供一個GNU編譯器套裝(GCC)的替代品。作者是克里斯·拉特納(Chris Lattner),在蘋果公司的贊助支援下進行開發,而原始碼授權是使用類BSD的伊利諾伊大學厄巴納-香檳分校開原始碼許可。Clang主要由C++編寫。

Clang專案包括Clang前端和Clang靜態分析器等。這個軟體專案在2005年由蘋果電腦發起,是LLVM(Low Level Virtual Machine)編譯器工具集的前端(front-end),目的是輸出程式碼對應的抽象語法樹(Abstract Syntax Tree, AST),並將程式碼編譯成LLVM Bitcode。接著在後端(back-end)使用LLVM編譯成平臺相關的機器語言。

Clang本身效能優異,其生成的AST所耗用掉的記憶體僅僅是GCC的20%左右。2014年1月發行的FreeBSD10.0版將Clang/LLVM作為預設編譯器。

        Clang效能:測試證明Clang編譯Objective-C程式碼時速度為GCC的3倍,還能針對使用者發生的編譯錯誤準確地給出建議。

        GCC與Clang區別

        GCC特性:除支援C/C++/ Objective-C/Objective-C++語言外,還是支援Java/Ada/Fortran/Go等;當前的Clang的C++支援落後於GCC;支援更多平臺;更流行,廣泛使用,支援完備。

        Clang特性:編譯速度快;記憶體佔用小;相容GCC;設計清晰簡單、容易理解,易於擴充套件增強;基於庫的模組化設計,易於IDE整合;出錯提示更友好。

        Clang採用的license是BSD,而GCC是GPLv3

        它們使用的巨集不同

        (1)、GCC定義的巨集包括:

__GNUC__
__GNUC_MINOR__
__GNUC_PATCHLEVEL__
__GNUG__
 (2)、Clang除了支援GCC定義的巨集之外還定義了:

__clang__
__clang_major__
__clang_minor__
__clang_patchlevel__
Clang vs GCC(GNU Compiler Collection):

Pro's of GCC vs clang:

(1)、GCC supports languages that clang does not aim to, such as Java, Ada, FORTRAN, Go, etc.

(2)、GCC supports more targets than LLVM.

(3)、GCC supports many language extensions, some of which are not implemented by Clang. For instance, in C mode, GCC supports nested functions and has an extension allowing VLAs in structs.

Pro's of clangvs GCC:

(1)、The Clang ASTs and design are intended to be easily understandable by anyone who is familiar with the languages involved and who has a basic understanding of how acompiler works. GCC has a very old codebase which presents a steep learning curve to new developers.

(2)、Clang is designed as an API from its inception, allowing it to be reused by source analysis tools, refactoring, IDEs (etc) as well as for code generation. GCC is built as a monolithic static compiler, which makes it extremely difficult to use as an API and integrate into other tools. Further, its historic design and current policy makes it difficult to decouple the front-end from the rest ofthe compiler.

(3)、Various GCC design decisions make it very difficult to reuse: its build system is difficult to modify, you can't link multiple targets into one binary, you can't link multiple front-ends into one binary, it uses a custom garbage collector, uses global variables extensively, is not reentrant or multi-threadable, etc. Clang has none of these problems.

(4)、Clang does not implicitly simplify code as it parses it like GCC does. Doing so causes many problems for source analysis tools: as one simple example, if you write"x-x" in your source code, the GCC AST will contain "0",with no mention of 'x'. This is extremely bad for a refactoring tool that wants to rename 'x'.

(5)、Clang can serialize its AST out to disk and read it back into another program, which is useful for whole program analysis. GCC does not have this. GCC's PCH mechanism(which is just a dump of the compiler memory image) is related, but is architecturally only able to read the dump back into the exact same executable as the one that produced it (it is not a structured format).

(6)、Clang is much faster and uses far less memory than GCC.

(7)、Clang has been designed from the start to provide extremely clear and concise diagnostics(error and warning messages), and includes support for expressive diagnostics.Modern versions of GCC have made significant advances in this area,incorporating various Clang features such as preserving typedefs in diagnostics and showing macro expansions, but GCC is still catching up.

(8)、GCC is licensed under the GPL license. clang uses a BSD license, which allows it to be embedded in software that is not GPL-licensed.

(9)、Clang inherits a number of features from its use of LLVM as a backend, including support for a bytecode representation for intermediate code, pluggable optimizers, link-time optimization support, Just-In-Time compilation, ability to link in multiple code generators, etc.

(10)、Clang's support for C++ is more compliant than GCC's in many ways.

(11)、Clang supports many language extensions, some of which are not implemented by GCC. For instance, Clang provides attributes for checking thread safety and extended vector types.

以上內容主要整理自: GCC維基百科  、  Clang維基百科 、 clang.llvm.org

相關文章