GCC Compiler is a very powerful and popular C compiler for various Linux distributions. This article explains some of the popular GCC compiler options.
An Example C Code
The following basic C code (main.c) will used in this article :
#include<stdio.h> int main(void) { printf("\n The Geek Stuff\n"); return 0; }
GCC Compiler Options
1. Specify the Output Executable Name
In its most basic form, gcc compiler can be used as :
gcc main.c
The above command executes the complete compilation process and outputs an executable with name a.out.
Use option -o, as shown below, to specify the output file name for the executable.
gcc main.c -o main
The command above would produce an output file with name ‘main’.
To understand the complete compilation process of a GCC compiler, read our article Journey of a C Program to Linux Executable in 4 Stages.
2. Enable all warnings set through -Wall option
This option enables all the warnings in GCC.
#include<stdio.h> int main(void) { int i; printf("\n The Geek Stuff [%d]\n", i); return 0; }
If the above code is compiled, the following warning related to uninitialized variable i is produced :
$ gcc -Wall main.c -o main main.c: In function ‘main’: main.c:6:10: warning: ‘i’ is used uninitialized in this function [-Wuninitialized]
3. Produce only the preprocessor output with -E option
The output of preprocessing stage can be produced using the -E option.
$ gcc -E main.c > main.i
The gcc command produces the output on stdout so you can redirect the output in any file. In our case(above), the file main.i would contain the preprocessed output.
4. Produce only the assembly code using -S option
The assembly level output can be produced using the -S option.
gcc -S main.c > main.s
In this case, the file main.s would contain the assembly output.
5. Produce only the compiled code using the -C option
To produce only the compiled code (without any linking), use the -C option.
gcc -C main.c
The command above would produce a file main.o that would contain machine level code or the compiled code.
6. Produce all the intermediate files using -save-temps function
The option -save-temps can do all the work done in example 4,5 and 6 above. Through this option, output at all the stages of compilation is stored in the current directory. Please note that this option produces the executable also.
For example :
$ gcc -save-temps main.c $ ls a.out main.c main.i main.o main.s
So we see that all the intermediate files as well as the final executable was produced in the output.
7. Link with shared libraries using -l option
The option -l can be used to link with shared libraries. For example:
gcc -Wall main.c -o main -lCPPfile
The gcc command mentioned above links the code main.c with the shared library libCPPfile.so to produce the final executable ‘main’.
8. Create position independent code using -fPIC option
While creating the shared libraries, position independent code should be produced. This helps the shared library to get loaded as any address instead of some fixed address. For this -fPIC option is used.
For example, the following commands create a shared library libCfile.so from source file Cfile.c:
$ gcc -c -Wall -Werror -fPIC Cfile.c $ gcc -shared -o libCfile.so Cfile.o
So we see that the option -fPIC was used in creation of a shared library.
9. Print all the executed commands using -V option
The option -v can be used to provide verbose information on all the steps gcc takes while compiling a source file.
For example :
$ gcc -Wall -v main.c -o main Using built-in specs. COLLECT_GCC=gcc COLLECT_LTO_WRAPPER=/usr/lib/gcc/i686-linux-gnu/4.6/lto-wrapper Target: i686-linux-gnu Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro 4.6.3-1ubuntu5' --with-bugurl=file:///usr/share/doc/gcc-4.6/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.6 --enable-shared --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.6 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --enable-plugin --enable-objc-gc --enable-targets=all --disable-werror --with-arch-32=i686 --with-tune=generic --enable-checking=release --build=i686-linux-gnu --host=i686-linux-gnu --target=i686-linux-gnu Thread model: posix gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5) ... ... ...
So we see that detailed information was produced in the output.
10. Enable the support of ISO C89 programs using -ansi option
Through -ansi option the support for ISO C89 style is enabled.
Consider the following code :
#include<stdio.h> int main(void) { // Print the string printf("\n The Geek Stuff\n"); return 0; }
If the above code is compiled with -ansi option then gcc would produce an error because the C++ comments are not allowed in ISO C89 style.
Here is the output :
$ gcc -Wall -ansi main.c -o main main.c: In function ‘main’: main.c:5:3: error: expected expression before ‘/’ token
So we see that gcc threw an error related to commenting style.
11. Interpret char as unsigned char using -funsigned-char option
Through this option, the char type is treated as unsigned type.
Here is an example :
#include<stdio.h> int main(void) { char c = -10; // Print the string printf("\n The Geek Stuff [%d]\n", c); return 0; }
When the above code is compiled with funsigned-char option, here is the output :
$ gcc -Wall -funsigned-char main.c -o main $ ./main The Geek Stuff [246]
So we see that the char was indeed treated as unsigned.
12. Interpret char as signed char using -fsigned-char option
This is the opposite of what we discussed in (12) above. Using this flag, the char variables are treated as signed.
Here is an example :
$ gcc -Wall -fsigned-char main.c -o main $ ./main The Geek Stuff [-10]
The output confirms that char was treated as signed.
13. Use compile time macros using -D option
The compiler option D can be used to define compile time macros in code.
Here is an example :
#include<stdio.h> int main(void) { #ifdef MY_MACRO printf("\n Macro defined \n"); #endif char c = -10; // Print the string printf("\n The Geek Stuff [%d]\n", c); return 0; }
The compiler option -D can be used to define the macro MY_MACRO from command line.
$ gcc -Wall -DMY_MACRO main.c -o main $ ./main Macro defined The Geek Stuff [-10]
The print related to macro in the output confirms that the macro was defined.
14. Convert warnings into errors with -Werror option
Through this option, any warning that gcc could report gets converted into error.
Here is an example :
#include<stdio.h> int main(void) { char c; // Print the string printf("\n The Geek Stuff [%d]\n", c); return 0; }
The compilation of above code should generate warning related to undefined variable c and this should get converted into error by using -Werror option.
$ gcc -Wall -Werror main.c -o main main.c: In function ‘main’: main.c:7:10: error: ‘c’ is used uninitialized in this function [-Werror=uninitialized] cc1: all warnings being treated as errors
15. Provide gcc options through a file using @ option
The options to gcc can also be provided through a file. This can be done using the @ option followed by the file name containing the options. More than one options are separated by a white space.
Here is an example :
$ cat opt_file -Wall -omain
The opt_file contains the options.
Now compile the code by providing opt_file along with option @.
$ gcc main.c @opt_file main.c: In function ‘main’: main.c:6:11: warning: ‘i’ is used uninitialized in this function [-Wuninitialized] $ ls main main
The output confirms that file opt_file was parsed to get the options and the compilation was done accordingly.
Comments on this entry are closed.
Great article again. Thanks for the information. Thanks for presenting this in a easily digestible and non-geeky manner…
As always excellent article.
Its very helpful to read the essentials of GNU C Compiler.
Thanks a lot.
Nice!!
You have a some what confusing typo in #12:
“Using this flag, the char variables are treated as unsigned.”
which I believe should be:
“Using this flag, the char variables are treated as signed.”
unsigned -> signed is the change required to correct it I think.
Cheers
@bgirardot,
Thanks for pointing out the typo. It is fixed now.
There is maybe something is wrong: ” gcc -C main.c” should be “gcc -c main.c ”
”
5. Produce only the compiled code using the -C option
To produce only the compiled code (without any linking), use the -C option.
gcc -C main.c “
Thankyou for providing this article.
Hi all,
please let me know if am i missing anything.
I tired option:15
[mcb@hdd-c12 C_prac]$ cat /etc/issue
Red Hat Enterprise Linux Server release 5.4 (Tikanga)
Kernel \r on an \m
[mcb@hdd-c12 C_prac]$ gcc -v
Using built-in specs.
Target: i686-pc-linux-gnu
Configured with: /usr/software/src/gcc-4.1.1/configure –prefix=/usr/software –program-suffix=-4.1.1
Thread model: posix
gcc version 4.1.1
[mcb@hdd-c12 C_prac]$
[mcb@hdd-c12 C_prac]$
[mcb@hdd-c12 C_prac]$ pwd
/u/mcb/fedor_prac/C_prac
[mcb@hdd-c12 C_prac]$ ls commands.c
commands.c
[mcb@hdd-c12 C_prac]$
[mcb@hdd-c12 C_prac]$ cat gcc_options
-Wall
[mcb@hdd-c12 C_prac]$ gcc commands.c @gcc_options
gcc: @gcc_options: No such file or directory
[mcb@hdd-c12 C_prac]$
Hi,
Very Nice…
hi,
with gcc -D, can we set the value to a macro ?
Nice article….
Nice article.
Have a doubt.When I execute ‘gcc -C main.c’ .The compiler give following error.
gcc: GCC does not support -C or -CC without -E
Then I executed it with -E option ”gcc -E -C main.c’.It worked fine.why that error came ?
nice tutorial..
I am very much confused with -MF -MM and -MT options in gcc .Can anyone please clear this doubt …….
Anirban
MM, MT, MF options is to generate dependencies automatically for “M”akefile.
you need to learn “make” command to understand those options
gr8 job !! n!ce
When I compile a C program using “gcc filename.c”, the result, if all goes well, appears immediately in the same directory with the name a.out no matter what the filename was.
I believe somehow I set this up long ago but I have no idea how this is controlled and would like to make it automatic with the original filename instead of a.out so I won’t have to type additional arguments or edit the filename later. I am running Ubuntu 9 and need to make this work on other machines running Ubuntu 12.4 and 14.4.
I have been new to Linux for 15 years and studying has done me no good.
Charles
Great collection!
Two other very important options are
-I/path/to/headers
This option adds a path to find headers files.
e.g.
$ gcc -I/home/codeman/include input-file.c
-std=standard
The most common options for standard are : c++11, c++14, c90, c89.
e.g.
$ gcc -std=c++11 hello-world.cpp
Thanks a ton Brother for the commendable work. Appreciated. May God Bless You.