【轉載】GCC與Clang / LLVM:C / C ++編譯器的比較

2020-08-13 15:45:43

部落格內容均爲轉載,摘取,如侵刪。
參考鏈接:
編譯器GCC與Clang的異同
GCC vs. Clang/LLVM: An In-Depth Comparison of C/C++ Compilers

這兩篇文章從多角度比較了這兩個編譯器。

背景

Visual C ++,GNU編譯器集合(GCC)和Clang /低階虛擬機器(LLVM)是業界三種主流的C / C ++編譯器。Visual C ++提供了圖形用戶介面(GUI),易於偵錯,但不適用於Linux平臺。因此,本文主要比較GCC與Clang / LLVM。

GCC是由GNU開發的程式語言編譯器。它是根據GNU通用公共許可證(GPL)和GNU較小通用公共許可證(LGPL)發佈的一組免費軟體。它是GNU和Linux系統的官方編譯器,也是用於編譯和建立其他UNIX操作系統的主要編譯器。

LLVM包含一系列模組化的編譯器元件和工具鏈。它可以在編譯,執行時和空閒時間優化程式語言和鏈接,並生成程式碼。LLVM可以作爲多種語言的編譯器的背景。Clang是一種C,C ++,Objective-C或Objective-C ++編譯器,它基於LLVM用C ++編譯,並根據Apache 2.0許可發行。Clang主要用於提供優於GCC的效能。

【轉載部落格】

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定義的宏包括:

  1. __GNUC__
  2. __GNUC_MINOR__
  3. __GNUC_PATCHLEVEL__
  4. __GNUG__
 (2)、Clang除了支援GCC定義的宏之外還定義了:

  1. __clang__
  2. __clang_major__
  3. __clang_minor__
  4. __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