clang(和LLVM)与gcc / g ++之间的区别是什么?

110

gcc和g++是用于C和C++代码的传统GNU编译器。最近,使用LLVM的clang(和clang++)作为备选编译器越来越受欢迎。

clang和gcc/g++有什么区别?使用clang是否有优势?


它们是各自系统的后端和前端,彼此之间没有关联。 - user541686
3
@Mehrdad,那并没有什么帮助。哪个是后端(我认为这意味着代码生成和链接),哪个是前端(我认为这意味着编译器驱动程序),它们与现有前端和后端相比的动机是什么?我还认为,虽然gcc可执行文件严格来说只是一个前端,但通常也习惯将整个从源代码到可执行文件的工具链称为"gcc"。其他编译器也是这样吗? - Peter - Reinstate Monica
2
这也是无稽之谈,'gcc'和'g++'都不是前端,也不是后端。它们是驱动程序,根据需要运行编译器、汇编器和/或链接器。gcc/g++运行的编译器可执行文件才有前端和后端。 - Jonathan Wakely
1个回答

200
GCC是一套庞大的软件集合。典型的过程是,GCC前端对代码进行词法分析和语法分析,转换成GCC内部的寄存器传输语言(RTL),然后由后端输出本地代码。
因此,一个典型的流程是:C代码 ---> GCC的C前端 ---> RTL ---> GCC的x86后端 ---> x86机器码。
GCC支持多个前端:C、C++、Java、Objective C、Go和Fortran。
GCC支持多个后端:32位x86、64位x86、小端ARM、大端ARM、MIPS、SPARC、PowerPC等。
前端将文本转换为RTL,后端将RTL转换为某种类型的机器码。
LLVM是一种中间层、与机器无关的计算表示,类似于GCC的RTL。它有自己的类型系统和指令集,称为LLVM中间表示(IR)。如果我理解正确,LLVM的IR比GCC的RTL更丰富、更表达性强,也更加灵活,从而带来了许多好处。LLVM的编译器前端可以用于许多不同语言的编译,都可编译成LLVM IR。这可用于“常规”语言,如C、C++、Java等,也可用于“非常规”编程任务,如GPU着色器或SQL查询

因此,LLVM可能是两个东西。LLVM-机器,即类型系统和指令集,可能更好地称为“LLVM IR”; LLVM-API是用于操作LLVM IR中的代码的软件,例如LLVM JIT编译器,或者可能是LLVM x86机器代码后端。

Clang是一个针对LLVM处理C系列语言(C、C ++、Objective C、Objective C ++)的前端。Clang将C/C++/etc转换为LLVM IR,LLVM对IR进行优化,LLVM x86后端编写x86机器代码以供执行。

尽管名字中带有“虚拟机”,但LLVM并不是传统意义上的虚拟机 - 它是一种计算模型和表示方法,非常适合于操作代码的任务。LLVM之所以受欢迎的部分原因在于它是一个完全具体化的编译器API。它可以用于对代码进行静态分析(“这段代码是否会意外地使用未初始化的内存?”)、优化、代码解析(例如用于构建IDE)。GCC的内部高度耦合,因此在这种方式下使用GCC非常困难。例如,GCC的前端在解析期间执行了一些优化,因此不可能总是获得完美的代码表示形式,例如报告错误和执行波浪线语法高亮,因为可能会丢失一些信息。据我所知,Clang保留了未经优化的解析语法,使第三方工具能够使用其输出并将转换等同于原始文本,最值得注意的是,Clang的错误消息更加有用,因为它们可以突出显示出问题的确切部分。

6
LLVM汇编通常被称为IR(中间表示),而不是IF。 - keltar
55
谢谢。我几乎一无所知。 - sapy
@sapy 同意。有人能否提供一个更易理解的版本,不要使用像reified这样的术语吗? - Sujay Phadke
4
“reified” 意为“使实际;完全实现;将抽象事物具体化”。如果您要设计一个专门提供编译器 API 的库,其中包括编译器除了仅生成机器代码之外的所有功能,那它会是什么样子呢? 显然,GCC 的主要目标是将文本转换为机器代码。LLVM 的目标则超越此范畴。 - antiduh
1
如果我正确理解您的帖子。1. GCC和LLVM都需要特定于架构的后端(64位x86,ARM等)。2. LLVM的好处是在转换为某些中间表示时不像GCC那样执行太多操作,因此人们可以使用LLVM IR做更多事情(例如分析)而不是GCC RTL? - Mr.Robot
2
@Mr.Robot - GCC平台的早期目标是使软件难以做除了作为一个单片编译器之外的任何事情。 Stallman是/仍然是一个深度偏执的人,并致力于他的信念。在发布开源编译器时,他担心其他人会拿走他的软件并使其执行他不想要的操作-例如将其部分集成到专有编译器中(即使这样做也会违反许可证)。他反对LLVM,因为它有一个宽松的许可证,从而使得它受益于开放和闭源编译器:https://lwn.net/Articles/582241/ - antiduh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接