"I will present here briefly some characteristics of both gcc and clang compilers.\n",
"\n",
"I recommend using them both (and more if you can!): each compiler gets its own spin on the standard, and sometimes a perfectly valid code will be refused by one... whereas (more often) invalid code will unduly get a free pass with one of the compiler.\n",
"I recommend using them both (and more if you can!): each compiler gets its own spin on the standard, and sometimes a perfectly valid code will be refused by one... whereas (more often) invalid code will unduly get a free pass with one of the compilers.\n",
"\n",
"So the more compiler with which you may test your code, the merrier!\n",
"\n",
...
...
@@ -36,7 +36,7 @@
"\n",
"[GCC](http://gcc.gnu.org/) is a free-to-use compiler which has now been around for decades; it is mostly for Unix systems but may be used with Windows with some additional set-up (I don't master this but see for instance this [StackOverflow question](https://stackoverflow.com/questions/771756/what-is-the-difference-between-cygwin-and-mingw)).\n",
"\n",
"As many others softwares, GCC changed its version system: gcc 3 and 4 were there for decades, and now the versions change more swiftly, with gcc 11 the current stable version (published on the 27th of April 2021).\n",
"As many others softwares, GCC changed its version system: gcc 3 and 4 were there for decades, and now the versions change more swiftly, with gcc 12.2 the current stable version (as of September 2022; it was published on the 19th of August 2022).\n",
"\n",
"`gcc` was long known for its terse user interface: until recently color were not provided in outputs, and error messages were a bit cryptic for the beotians. It changed though when `clang` appeared.\n",
"\n",
...
...
@@ -65,7 +65,7 @@
"* `-DNDEBUG` means the macro `NDEBUG` is defined; this deactivates all asserts in the code.\n",
"* `-O3` means as many optimizations as possible should be applied.\n",
"\n",
"You may sometimes find on the Web advocates of `-O2` flag, which performs slightly less optimization than `-O3`, on the ground that `-O3` breaks some code. It was true many years ago... but now if your code breaks under `-O3` it probably means it's buggy, not that optimization is! You may read [this thread](https://stackoverflow.com/questions/11546075/is-optimisation-level-o3-dangerous-in-g) for more about the question; I raised this point because you might be surprised by the number of libraries which use up O2 in their release mode.\n",
"You may sometimes find on the Web advocates of `-O2` flag, which performs slightly less optimization than `-O3`, on the ground that `-O3` breaks some code. It was true many years ago... but now if your code breaks under `-O3` it probably means it's buggy, not that optimization is! You may read [this thread](https://stackoverflow.com/questions/11546075/is-optimisation-level-o3-dangerous-in-g) for more about the question; I raised this point because you might be surprised by the number of libraries which still use up O2 in their release mode.\n",
"\n",
"\n",
"### Warnings\n",
...
...
@@ -130,7 +130,7 @@
"-Wno-global-constructors // same\n",
"-Wno-documentation // Some Doxygen were incorrectly indicated as inadequate\n",
"-Wno-documentation-unknown-command // A valid Doxygen command I used was not recognized\n",
"-Wno-undefined-func-template // Required weird code in header file; didn't understand this one to be honest\n",
"-Wno-undefined-func-template // Requires weird code in header file; didn't understand this one to be honest\n",
"-Wno-c++1z-extensions // I assume my code uses up C++ 17\n",
"-Wno-unused-template // A very recent one that tells if a template is never used \n",
"````\n",
...
...
@@ -151,7 +151,9 @@
"\n",
"### Fortran support\n",
"\n",
"There is no Fortran compiler with LLVM or clang; you should therefore use gfortran if a third-party library you use require it. Usually take the most recent you may find.\n",
"For a long time, there was no Fortran compiler with LLVM or clang; you therefore had to use something as gfortran if a third-party library you use require it - usually the most recent you may find.\n",
"\n",
"As of 2022, there is something called Flang that exists, but my attempt to use it didn't go far as they chose contrary to clang did years ago to use their own options without pseudo backward compatibility with gfortran's ones. As a result, compilation of third party libraries is tricky as they often assume interface provided by gfortran (Openblas and PETSc for instance won't compile with Flang). So for the time being the best is probably to stick with gfortran if as myself you aren't a Fortran developer but may need it for your third party dependencies.\n",
"\n",
"### Apple Clang\n",
"\n",
...
...
@@ -229,5 +231,5 @@
}
},
"nbformat": 4,
"nbformat_minor": 2
"nbformat_minor": 4
}
%% Cell type:markdown id: tags:
# [Getting started in C++](./) - [C++ in a real environment](./0-main.ipynb) - [Clang ang gcc compilers](./3-Compilers.ipynb)
%% Cell type:markdown id: tags:
<h1>Table of contents<spanclass="tocSkip"></span></h1>
<divclass="toc"><ulclass="toc-item"><li><span><ahref="#Introduction"data-toc-modified-id="Introduction-1">Introduction</a></span></li><li><span><ahref="#GNU-compiler"data-toc-modified-id="GNU-compiler-2">GNU compiler</a></span><ulclass="toc-item"><li><span><ahref="#Debug-and-release-flags"data-toc-modified-id="Debug-and-release-flags-2.1">Debug and release flags</a></span><ulclass="toc-item"><li><span><ahref="#Debug-mode"data-toc-modified-id="Debug-mode-2.1.1">Debug mode</a></span></li><li><span><ahref="#Release-mode"data-toc-modified-id="Release-mode-2.1.2">Release mode</a></span></li></ul></li><li><span><ahref="#Warnings"data-toc-modified-id="Warnings-2.2">Warnings</a></span></li><li><span><ahref="#Standard-library"data-toc-modified-id="Standard-library-2.3">Standard library</a></span></li><li><span><ahref="#Fortran-support"data-toc-modified-id="Fortran-support-2.4">Fortran support</a></span></li></ul></li><li><span><ahref="#clang"data-toc-modified-id="clang-3">clang</a></span><ulclass="toc-item"><li><span><ahref="#Debug-and-release-mode"data-toc-modified-id="Debug-and-release-mode-3.1">Debug and release mode</a></span></li><li><span><ahref="#Warnings"data-toc-modified-id="Warnings-3.2">Warnings</a></span></li><li><span><ahref="#Standard-library"data-toc-modified-id="Standard-library-3.3">Standard library</a></span></li><li><span><ahref="#Fortran-support"data-toc-modified-id="Fortran-support-3.4">Fortran support</a></span></li><li><span><ahref="#Apple-Clang"data-toc-modified-id="Apple-Clang-3.5">Apple Clang</a></span></li></ul></li><li><span><ahref="#Wandbox"data-toc-modified-id="Wandbox-4">Wandbox</a></span></li></ul></div>
%% Cell type:markdown id: tags:
## Introduction
I will present here briefly some characteristics of both gcc and clang compilers.
I recommend using them both (and more if you can!): each compiler gets its own spin on the standard, and sometimes a perfectly valid code will be refused by one... whereas (more often) invalid code will unduly get a free pass with one of the compiler.
I recommend using them both (and more if you can!): each compiler gets its own spin on the standard, and sometimes a perfectly valid code will be refused by one... whereas (more often) invalid code will unduly get a free pass with one of the compilers.
So the more compiler with which you may test your code, the merrier!
If you're Inria staff, Inria also provides a licence to [Intel compiler](https://software.intel.com/en-us/c-compilers).
## GNU compiler
[GCC](http://gcc.gnu.org/) is a free-to-use compiler which has now been around for decades; it is mostly for Unix systems but may be used with Windows with some additional set-up (I don't master this but see for instance this [StackOverflow question](https://stackoverflow.com/questions/771756/what-is-the-difference-between-cygwin-and-mingw)).
As many others softwares, GCC changed its version system: gcc 3 and 4 were there for decades, and now the versions change more swiftly, with gcc 11 the current stable version (published on the 27th of April 2021).
As many others softwares, GCC changed its version system: gcc 3 and 4 were there for decades, and now the versions change more swiftly, with gcc 12.2 the current stable version (as of September 2022; it was published on the 19th of August 2022).
`gcc` was long known for its terse user interface: until recently color were not provided in outputs, and error messages were a bit cryptic for the beotians. It changed though when `clang` appeared.
### Debug and release flags
#### Debug mode
As a reminder, debug mode is the one you should use to develop: it is intended to compile code as fast as possible, and doesn't spend time performing some optimizations. Typical debug flags are:
`-O0 -g`
where:
*`-O0` means no optimization is applied. It might be skipped: it is the default behaviour.
*`-g` means symbols are kept for debug purposes, enabling a debugger to do its bidding.
#### Release mode
On release mode, the goal is more to provide an efficient code, at the cost of higher compilation time. Typical flags are:
`-O3 -DNDEBUG`
where:
*`-DNDEBUG` means the macro `NDEBUG` is defined; this deactivates all asserts in the code.
*`-O3` means as many optimizations as possible should be applied.
You may sometimes find on the Web advocates of `-O2` flag, which performs slightly less optimization than `-O3`, on the ground that `-O3` breaks some code. It was true many years ago... but now if your code breaks under `-O3` it probably means it's buggy, not that optimization is! You may read [this thread](https://stackoverflow.com/questions/11546075/is-optimisation-level-o3-dangerous-in-g) for more about the question; I raised this point because you might be surprised by the number of libraries which use up O2 in their release mode.
You may sometimes find on the Web advocates of `-O2` flag, which performs slightly less optimization than `-O3`, on the ground that `-O3` breaks some code. It was true many years ago... but now if your code breaks under `-O3` it probably means it's buggy, not that optimization is! You may read [this thread](https://stackoverflow.com/questions/11546075/is-optimisation-level-o3-dangerous-in-g) for more about the question; I raised this point because you might be surprised by the number of libraries which still use up O2 in their release mode.
### Warnings
To my mind, `gcc` is a bit of a mess on the warning side...
There is the flag:
`-Wall`... which activates _some_ warnings, and not all as its name suggests.
You may add:
`-Wextra`... which add some others.
So how to activate them all? No reliable way; my current batch of gcc warnings is (brace yourself!):
Some are intentionaly deactivated, and plenty others I probably don't know - especially if they were introduced since I established this list (by adapting one provided on StackOverflow...).
### Standard library
GNU also provides its implementation of the standard C++ library, which is called **libstdc++**.
### Fortran support
GNU compiler suite also provides a Fortran compiler, which is often required for many mathematical libraries that use part of this language in their implementation.
## clang
[clang](http://clang.llvm.org/) is a much more recent project (2007) that proposes an interface mostly similar to the one provided by gcc.
This is the compiler I recommend for your development: interface is much more user friendly - even if gcc took note and made progresses on that front. But clang gets for itself:
* Default syntax coloring of the output.
* More helpful compilation error: there is even an arrow to indicate where in a line the syntax is problematic.
* Faster compilation in debug mode.
### Debug and release mode
See gcc: they took the same.
### Warnings
clang provides many warnings that are the same as gcc... but:
* Some do not behave exactly the same way. For instance I activate `-Wshadow` in clang but not in gcc where it is too cumbersome for my taste.
* Some are specific to a compiler... and it becomes truer with each new version of clang, which often introduces a new warning.
But what I really like with clang is they took the opposite approach warning side: they provide a `-Weverything` which really activates all of them! (`-Wall -Wextra` are also supported but similar to their gcc counterparts).
Of course, you may deactivate a warning you do not want by adding -Wno-foo where _foo_ is the warning not to consider.
In my code, compilation warnings I use are:
````
-Weverything
-Wno-c++98-compat // I assume my code is not C++ 03 compatible
-Wno-c++98-compat-pedantic // same for pedantic warnings
-Wno-padded // I don't want to add char data attributes to make the static size of a class a multiple of 4
-Wno-exit-time-destructors // I use an advanced pattern that doesn't mesh with this one.
-Wno-global-constructors // same
-Wno-documentation // Some Doxygen were incorrectly indicated as inadequate
-Wno-documentation-unknown-command // A valid Doxygen command I used was not recognized
-Wno-undefined-func-template // Required weird code in header file; didn't understand this one to be honest
-Wno-undefined-func-template // Requires weird code in header file; didn't understand this one to be honest
-Wno-c++1z-extensions // I assume my code uses up C++ 17
-Wno-unused-template // A very recent one that tells if a template is never used
````
What's neat is that your build remains up-to-date with `-Weverything`: if a new warning is added you will possibly see it if your code is affected and then decide if you want to keep it or not.
### Standard library
A new implementation of the standard library is also delivered with clang; it is named **libc++**. I advise you to use it rather than libstdc++ with clang; however it is easier said than done on Ubuntu (at least the last time I tried).
To ensure that, add in your command line:
````
-stdlib=libc++
````
Your build system may already take care of this automatically.
### Fortran support
There is no Fortran compiler with LLVM or clang; you should therefore use gfortran if a third-party library you use require it. Usually take the most recent you may find.
For a long time, there was no Fortran compiler with LLVM or clang; you therefore had to use something as gfortran if a third-party library you use require it - usually the most recent you may find.
As of 2022, there is something called Flang that exists, but my attempt to use it didn't go far as they chose contrary to clang did years ago to use their own options without pseudo backward compatibility with gfortran's ones. As a result, compilation of third party libraries is tricky as they often assume interface provided by gfortran (Openblas and PETSc for instance won't compile with Flang). So for the time being the best is probably to stick with gfortran if as myself you aren't a Fortran developer but may need it for your third party dependencies.
### Apple Clang
As a side note: macOS provides for few years now a customized clang with its developer environment. This one is not the standard clang and is usually slightly older than the bleeding-edge clang you may find on LLVM site. The drawback is that they stopped indicating the base version upon which their version is built; so it's not that easy to find on the Web whether a feature is supported or not.
%% Cell type:markdown id: tags:
## Wandbox
If you need to know whether a small code is supported by a specific version of clang or gcc, you may use the online compiler facility [Wandbox](https://wandbox.org/) which provides many gcc and clang versions (and even Boost library for good measure).
_This notebook is an adaptation of a lecture prepared by David Chamont (CNRS) under the terms of the licence [Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0)](http://creativecommons.org/licenses/by-nc-sa/4.0/)_
_The present version has been written by Sébastien Gilles and Vincent Rouvreau (Inria)_