Clang vs GCC (GNU Compiler Collection) URL:


Pro’s of GCC vs clang:

  • GCC supports languages that clang does not aim to, such as Java, Ada, FORTRAN, etc.
  • GCC supports more targets than LLVM.

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.
  • For every token, clang tracks information about where it was written and where it was ultimately expanded into if it was involved in a macro. GCC does not track information about macro instantiations when parsing source code. This makes it very difficult for source rewriting tools (e.g. for refactoring) to work in the presence of (even simple) macros.
  • 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 aims to provide extremely clear and concise diagnostics (error and warning messages), and includes support for expressive diagnostics. GCC’s warnings are sometimes acceptable, but are often confusing and it does not support expressive diagnostics. Clang also preserves typedefs in diagnostics consistently, showing macro expansions and many other features.
  • 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 (e.g. conformant two phase name lookup).

Differences warnings in standard commands compile gcc and clang


warnings on gcc

gcc TCP-Syn-port-scanner.c -o TCP-Syn-port-scanner
/tmp/ccFPV136.o: In function `main’:
TCP-Syn-port-scanner.c:(.text+0x3b9): undefined reference to `pthread_create’
TCP-Syn-port-scanner.c:(.text+0x540): undefined reference to `pthread_join’
collect2: error: ld returned 1 exit status

warnings on clang

$clang TCP-Syn-port-scanner.c -o TCP-Syn-port-scanner
TCP-Syn-port-scanner.c:189:5: warning: implicit declaration of function ‘start_sniffer’ is invalid in C99 [-Wimplicit-function-declaration]
TCP-Syn-port-scanner.c:190:1: warning: control reaches end of non-void function [-Wreturn-type]
TCP-Syn-port-scanner.c:219:71: warning: passing ‘int *’ to parameter of type ‘socklen_t *’ (aka ‘unsigned int *’) converts between pointers to integer types with different sign [-Wpointer-sign]
data_size = recvfrom(sock_raw , buffer , 65536 , 0 , &saddr , &saddr_size);
/usr/include/x86_64-linux-gnu/sys/socket.h:168:27: note: passing argument to parameter ‘__addr_len’ here
socklen_t *__restrict __addr_len);
TCP-Syn-port-scanner.c:232:5: warning: implicit declaration of function ‘close’ is invalid in C99 [-Wimplicit-function-declaration]
TCP-Syn-port-scanner.c:347:1: warning: control reaches end of non-void function [-Wreturn-type]
5 warnings generated.
/tmp/TCP-Syn-port-scanner-stjuCw.o: In function `main’:
TCP-Syn-port-scanner.c:(.text+0x4c4): undefined reference to `pthread_create’
TCP-Syn-port-scanner.c:(.text+0x6b6): undefined reference to `pthread_join’
clang: error: linker command failed with exit code 1 (use -v to see invocation)