Different Options for the GNU gcc (C Compiler Program)

In this blog, I will be talking about the Linux GNU gcc compiler for the C programming language on a Linux system.

Here is a basic C program to print the output to the user “Hello World!”

#include <stdio.h.>

int main() {

     printf(“Hello World!\n”);

}

Now to enable some options in the gcc compiler before compiling the C program.

Options:

-g

(For enabling the debugger)

-fno-builtin

(For disabling the built-in function optimizer)

-O0

(For removing all optimization of the code)

The command to run is: gcc -g -fno-builtin -O0 -o hello hello.c

I will also use the objdump program that can be used on a Linux system to read the assembly language code of the C program.

The command is: objdump -f -s -d –source hello

I will only require the start and main sections of the program.

Note: I will be using an arm aarch64 Linux Fedora system for this test.

The start section is show below:

0000000000400490 <_start>:
400490: d280001d mov x29, #0x0 // #0
400494: d280001e mov x30, #0x0 // #0
400498: aa0003e5 mov x5, x0
40049c: f94003e1 ldr x1, [sp]
4004a0: 910023e2 add x2, sp, #0x8
4004a4: 910003e6 mov x6, sp
4004a8: d2e00000 movz x0, #0x0, lsl #48
4004ac: f2c00000 movk x0, #0x0, lsl #32
4004b0: f2a00800 movk x0, #0x40, lsl #16
4004b4: f280b280 movk x0, #0x594
4004b8: d2e00003 movz x3, #0x0, lsl #48
4004bc: f2c00003 movk x3, #0x0, lsl #32
4004c0: f2a00803 movk x3, #0x40, lsl #16
4004c4: f280b703 movk x3, #0x5b8
4004c8: d2e00004 movz x4, #0x0, lsl #48
4004cc: f2c00004 movk x4, #0x0, lsl #32
4004d0: f2a00804 movk x4, #0x40, lsl #16
4004d4: f280c704 movk x4, #0x638
4004d8: 97ffffde bl 400450 <__libc_start_main@plt>
4004dc: 97ffffe5 bl 400470 <abort@plt>

The main section is shown below:

0000000000400594 <main>:
#include <stdio.h>

 

int main() {
400594: a9bf7bfd stp x29, x30, [sp, #-16]!
400598: 910003fd mov x29, sp
printf(“Hello World!\n”);
40059c: 90000000 adrp x0, 400000 <_init-0x418>
4005a0: 9119c000 add x0, x0, #0x670
4005a4: 97ffffb7 bl 400480 <printf@plt>
4005a8: 52800000 mov w0, #0x0 // #0
}
4005ac: a8c17bfd ldp x29, x30, [sp], #16
4005b0: d65f03c0 ret
4005b4: 00000000 .inst 0x00000000 ; undefined

#Check for the line for output
4005ac: a8c17bfd ldp x29, x30, [sp], #16

 

Using a static library:

An option can be added to the gcc compiler called “-static”

Command: gcc -g -fno-builtin – static -O0 -o hello hello.c

What this option does is link the libraries for the gcc compiler to a static location as explained here: https://www.systutorials.com/5217/how-to-statically-link-c-and-c-programs-on-linux-with-gcc/

Checking the size

Before static option:

73144 bits

After static option:

631624 bits

This causes the compiler to output a larger file size. The reasoning for using the -static option in the gcc compiler is for build testing without the system updates of system library files.

Also you can find the -static option on the gcc man help page under ¨Linker Options¨

 

Removing the -fno-builtin option will allow the gcc compiler to optimize the functions in the C Programming code file (.c file).

Command: gcc -g -static -O0 -o hello hello.c

Recompiling will give us a file size of: 631608 bits (Saving 16 bits of file size)

Most of the time, it is not wise to enable this option because of optimization issues.

Removing the -g option for debugger setting will reduce the file size even more when recompiled.

Command: gcc -static -O0 -o hello hello.c

The Size is: 629120 bits

This removes the extra, technical data being sent into the program. The debugger information is for another programmer to read and review the code but it maybe more useful for  remove the data for reduced file size of the C Program.

The compiler is running with the function optimization feature on (removed the -fno-builtin from the previous tests)

What will happen to the program size when the program is like this:

#include <stdio.h>
int output();

int main() {
     output();
}

int output() {
     printf(“Hello World!\n””This is 1\n”);
}

Note: The printf() line is sent to a function outside of the main() function.

The size of the file is: 629144 bits. There is another increase in file size. Using a function will increase the size of the program even with the default function optimization built-in the gcc compiler. The more functions in the program will equal an increase in file size.

The final test is to change the default optimization level ¨-O0¨ to ¨-O3¨

Command: gcc -O3 -o hello hello.c

Note: There is a list of optimization level here: https://www.rapidtables.com/code/linux/gcc/gcc-o.html

¨-O3¨ is the highest optimization level option for the gcc compiler.

Size = 629168 bits

Changing the optimization level from 0 to 3 causes the compiler to  use more memory from the system and use more time to compile the C language code into the C Program.

Conclusion: Only if there was a one-click button for optimization instead of all of these options for the compiler.

 

 

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s