linux下Clang和gcc的区别

Clang 比 GCC 编译器的优势:

编译速度更快

编译产出更小

出错提示更友 好,比如 clang 在编译过程可以直接指出相对简单的出错位置以及它 “ 认为 ” 正确的方式 。

内置有静态分析工具,可以对代码进行静态分析 (clang—analyze) 。这也是 gcc 做不到的 。

专注,因为 clang 只需要完成词法和语法分析,代码优化和机器代码的生成工作由 llvm 完成。所以和全部由自己包下的 gcc 比起来, clang 可以更专注地做好一件事。这种结构也使 clang 可以被单独拿出来用在其他的程序里,成为其它 app (主要是 IDE)的内嵌 C/C++ parser 。 对于 IDE 而言,代码补全、重构是重要的功能,然而如果没有底层的支持,只使用 tags 分析或是正则表达式匹配是很难达成的, clang正好充当了这一角色。 这样, editor 工具可以使用和 compiler 一样的 parser 来完成 edit-time 的语法检查 。 而 gcc 就没法很方便地做到这一点 。由于历史原因, GCC 是一个单一的可执行程序编译器,其内部完成了从预处理到最后代码生成的全部过程,中间诸多信息都无法被其他程序重用。

Gcc 的优势:

· 一些软件用 clang 编译会出现莫名其妙的错误,但是用 gcc 编译可以通过 。

· GCC 在 5.0 之前一直都在准备用 C++ 实现模块化,期待 GCC 的 5.0 会有所突破,补上无法模块化的短板。


编译速度更快、编译产出更小、出错提示更友好。尤其是在比较极端的情况下。 两年多前曾经写过一个Scheme解释器,词法分析和语法解析部分大约2000行,用的是Boost.Spirit——一个重度依赖C++模版元编程的框架。当时用g++ 4.2编译的情况是:

  1. 编译速度极慢:完整编译一次需要20分钟
  2. 编译过程中内存消耗极大:单个g++实例内存峰值消耗超过1G
  3. 中间产出物极大:编译出的所有.o文件加在一起大约1~2G,debug链接产物超过200M
  4. 编译错误极其难以理解:编译错误经常长达几十K,基本不可读,最要命的是编译错误经常会长到被g++截断,看不到真正出错的位置,基本上只能靠裸看代码来调试

这里先不论我使用Spirit的方式是不是有问题,或者Spirit框架自身的问题。我当时因为实在忍受不了g++,转而尝试clang。当时用的是clang 2.8,刚刚可以完整编译Boost,效果让我很满意:

  1. 编译速度有显著提升,记得大约是g++的1/3或1/4
  2. 编译过程中的内存消耗差别好像不大
  3. 中间产出物及最终链接产物,记得也是g++的1/3或1/4
  4. 相较于g++,编译错误可读性有所飞跃,至少不会出现编译错误过长被截断的问题了

当时最大的缺点是clang编译出的可执行文件无法用gdb调试,需要用调试器的时候还得用g++再编译一遍。不过这个问题后来解决了,我不知道是clang支持了gdb还是gdb支持了clang。至少我当前在Ubuntu下用clang 3.0编译出的二进制文件已经可以顺利用gdb调试了。

最后一点,其他同学也有讲到,就是Clang采用的是BSD协议。这是苹果资助LLVM、FreeBSD淘汰GCC换用Clang的一个重要原因。


Clang vs GCC (GNU Compiler Collection)

Pro's of GCC vs clang:

  • GCC supports languages that clang does not aim to, such as Java, Ada, FORTRAN, Go, etc.
  • GCC supports more targets than LLVM.
  • 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 clang vs GCC:

  • 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 a compiler works. GCC has a very old codebase which presents a steep learning curve to new developers.
  • 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 of the compiler.
  • 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.
  • 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'.
  • 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).
  • Clang is much faster and uses far less memory than GCC.
  • 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.
  • 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.
  • 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.
  • Clang's support for C++ is more compliant than GCC's in many ways.
  • 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.

本文分享自微信公众号 - Linux阅码场(LinuxDev)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-06-21

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏我是攻城师

Spring Boot如何集成Nginx配置代理

配置Nginx统一代理web容器如tomcat,jetty的请求,在日常开发中很常见,那么在配置集成的时候应该注意些什么呢?

54530
来自专栏欧阳大哥的轮子

用expect脚本实现Xcode对越狱设备的动态库注入

如果我们想远程登录或者控制一台机器,可以在被操控的设备上安装ssh服务。无论是本地设备使用命令行还是可视化工具都需要预先登录到远程设备中,登录过程需要输入用户名...

11430
来自专栏java技术大本营

java练习本(原每日一练)(2019-04-18)

“Love yourself first and everything else falls into line. You really have to lov...

11010
来自专栏Devops专栏

jquery 置顶菜单

注意:当Banner图片完全上移出了浏览器可视区域,此时菜单固定定位在文档的最上方。

16120
来自专栏深度学习和计算机视觉

从零开始一起学习SLAM | 掌握g2o边的代码套路

师兄:在《g2o: A general Framework for (Hyper) Graph Optimization》这篇文档里,我们找到那张经典的类结构图...

15120
来自专栏Devops专栏

CSS 块元素、内联元素、内联块元素

元素就是标签,布局中常用的有三种标签,块元素、内联元素、内联块元素,了解这三种元素的特性,才能熟练的进行页面布局。

13120
来自专栏搜狗测试

Fiddler成长之路 - 如何将https修改为http协议

方法二: Fiddler里的Rules—>Customize Rules, 在static functionOnBeforeRequest(oSession:...

71350
来自专栏搜狗测试

Code Review之delete后置空

大部分同学应该都发现了,单例的destoryInstance函数没有在delete之后将s_pInstance 置空。本次使用没问题,但下次getInstanc...

10630
来自专栏数值分析与有限元编程

《Introduction to Programming with Fortran(2018)》 4th edition

本书官方网站: https://www.fortranplus.co.uk/ 提供相关源代码下载。

14120
来自专栏深度学习和计算机视觉

利用OpenCV实现图像修复(含源码链接)

前一段时间小白分享过关于图像修复技术介绍的推文(点击可以跳转),有小伙伴后台咨询能不能分享一下关于图像修复的项目或者程序。今天小白带着满满的诚意,带来了通过Op...

39440

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励