10 Flags and Parameters Tips for GNU GCC
The main parameters of GNU GCC
The GNU GCC is a collection of compilers that was initially created only for the C language and the acronym meant GNU C Compiler, but over time several other programming languages were added, such as: C++, Objective-C, Objective-C++, Fortran, Ada, D, Go, Rust and Java. And the meaning of the acronym became: GNU Compiler Collection.
How to install GNU GCC
For Windows specifically, you can also directly access this link: How to Install GCC/G++ MinGW on Windows and on any other system just use their package manager.
All the links mentioned here I will leave in the description of this video.
It is also necessary to remember that almost 100% of the flags and parameters used by GCC also work with the
clang++ compilers. They’ve already done this on purpose for compatibility, in case companies want to migrate in the future.
The difference between flag and parameter is that the flag influences the binary to be generated, the parameter does not, that is, it is used for programs already built. A compiler can have both (because it is also a program, but it builds binaries), whereas a program only uses parameters.
Now let’s get to know 10 most used GNU GCC flags and parameters!
01. Basic compilation
First of all check your compiler version with
g++ --version or
gcc --version, some things might not work if your version is too old.
In a basic C/C++ code to compile just use the command:
gcc for C language and
g++ for C++. Examples:
Some alternative commands to gcc/g++ can be: basic mode, alias or symbolic link are:
To compile, run:
In fact, the
cc command was the standard C compiler for Unix, but the source code was not available.
02. Using the
If you want to save to a different binary name, use the
g++as a base, but use
gccif you want to achieve the same result.
-Wall flag means
Warnig all. When there is a flag starting with
W that means it is to detect warnings, in this case for all/all, actually a set of flags, there are more than 40 .
Suppose you created a variable and didn’t use it anywhere in your code. If you compile normally, this will pass, but if you use
-Wall, the compiler will warn you:
g++ -Wall main.cpp
Even so the program compiles, it’s just a warning. If you want to turn this warning into an error, i.e., not compile if there is a warning, you need to combine this flag with another flag which is
-Werro, it treats the warning as an error:
That is, if you remove the binary and recompile, note that the binary will not be built.
-gparameter is used for debugging at the operating system level. It’s always good to use it in conjunction with
-Wall and -Werror.
04. Extra checks for warnings/warnings
If we use this variable, note that compilation will pass even with
-Wall and -Werror:
But notice that we have the function arguments being passed but not being used. To stop this we can use the flag:
-Wextra, but it needs to be together with
-Wall and -Werror:
Either we use these parameters or we need to remove them.
Formerly there was a bug in the compilers that even if you removed it, it was possible to obtain parameters via the command line, for that there was the technique of using the
void parameter, but this is no longer necessary:
05. Be pedantic
According to the dictionary, pedantic is one who cares excessively about small details or rules and the name justifies it.
That is, the
-pedantic parameter checks if your code complies with ISO rules, for example:
When compiling, note:
-pendatic-errorsdoes not enable as an error, it is like an alias for
06. Being verbose
You can see all the compiler steps using the
This is usually enabled by default on systems that compile from scratch, like Gentoo, for example, which is where I’m at.
07. Disinfectant for memory
Sanitizers was developed by Google and is such well-made software that it has been natively adopted by the GNU GCC: https://github.com/google/sanitizers.
It checks for memory violations and as its name suggests: disinfects!
Suppose we have this code:
If we compile normally and run it several times, note that nothing will be displayed, but in one of the executions it will present the bug:
Now if we compile with Sanitize:
Note that running the program will not run and will give you details of the addressing violation:
Observation: Note that the size of the binary grows a lot when using it, that way you understand why some programming languages that call themselves safe memory have such large binaries, because they already have all these flags by default activated in the compiler . I particularly think this is bad, because the programmer doesn’t know what he’s doing. But, if you want you can create a Bash function in your
~/.bashrcand add all parameters to gcc/g++ automatically, including static analyzers and other tools, but remember your binaries will grow significantly!
08. Separating header inclusion
In the GTKmm series we use the
-MMD parameter. It serves to separate the headers and include them later in the linker.
First of all let’s know what the linker is about. It is a program that merges two binary files together.
Suppose we have this code that needs to compile 2
We could compile like this directly:
g++ main.cpp class.cpp.
But, using the linker (in GCC the linker can use gcc/g++ itself) we can separate the headers and optimize our compilation:
However, when there are many headers, it can be duplicated several times to include them, so the
-MMD parameter is used.
To make it easy to understand, let’s use the GTKmm series project that is at: https://github.com/terroo/pass-firefox
Let’s clone, check the Makefile and modify.
That is, the headers are in a separate file to be included later by the linker.
09. View the generated assembly code
C/C++ compilers create assembly code and then compile assembly code. That’s why the new programming languages are seen as a front-end for C/C++, more precisely the C++ that LLVM is written on.
There are several assembly compilers, and GNU GCC has its own which is the GNU Assembler (an alternative to NASM), and uses the
To generate assembly code:
View the generated assembly code:
as to generate the binary:
Now just compile
10. Optimizing the binary
We’ve talked about situations where the size of the binary can get quite large depending on the flags you pass in, but this can be improved by using the
-O2 flag, actually you can use several numbers:
-O3, …. but above 2 it’s dangerous depending on the machine you’re compiling, simple machines (2 processors and 8GB of RAM) it’s better to use a maximum of
The GNU GCC is huge, it has a world of flags and parameters, for everyone use the manual: