-c flag tells
gcc to compile the program and generate machine code, but not to link it or generate an executable:
$ gcc hello.c -c
The result is a file named
hello.o, where the
o stands for object code, which is the compiled program. Object code is not executable, but it can be linked into an executable.
The UNIX command
nm reads an object file and generates information about the names it defines and uses. For example:
$ nm hello.o 0000000000000000 T main U puts
This output indicates that
hello.o defines the name
main and uses a function named
puts, which stands for “put string”. In this example,
gcc performs an optimization by replacing
printf, which is a large and complicated function, with
puts, which is relatively simple.
You can control how much optimization
gcc does with the
-O flag. By default, it does very little optimization, which can make debugging easier. The option
-O1 turns on the most common and safe optimizations. Higher numbers turn on additional optimizations that require longer compilation time.
In theory, optimization should not change the behavior of the program, other than to speed it up. But if your program has a subtle bug, you might find that optimization makes the bug appear or disappear. It is usually a good idea to turn off optimization while you are developing new code. Once the program is working and passing appropriate tests, you can turn on optimization and confirm that the tests still pass.