The compile command on the previous page was gcc sort.c -o sort.
That works, but it leaves several useful checks turned off and the
binary harder to debug than it has to be. From here on out we will
use four flags every time we compile.
gcc -Wall -Wextra -g sort.c -o sort-Wall and -Wextra
You met these in f04/01. They turn on the warnings the compiler can
produce. -Wall enables most of the common ones; -Wextra adds a
few more that catch real mistakes (assigning a value you never use,
comparing signed and unsigned types, leaving variables uninitialised
in some code paths). Together they catch a lot at compile time, for
free.
Treat warnings as errors during development. If the compiler is telling you something looks wrong, it usually does. Recompile sort with these flags now:
gcc -Wall -Wextra sort.c -o sortIf it compiles silently, good. The bugs we are about to hunt are not the kind warnings can catch — they manifest at runtime, not compile time.
-g
-g tells gcc to include debug symbols in the binary. Debug
symbols are a table mapping every machine instruction in the
executable back to the source file and line number it came from.
With them, gdb can show you the actual line of sort.c your
program is running, set breakpoints by function name, and print
the values of named variables. Without them, the debugger only
sees raw memory addresses and assembly.
Every binary we build for the rest of this chapter will use -g.
If you forget, the next three pages will not work — gdb will
show you addresses instead of code, valgrind will report a leak
without a line number, and the sanitiser stack traces will be
unintelligible.
gcc -Wall -Wextra -g sort.c -o sortThe binary gets larger by a few kilobytes, but that does not matter during development. You strip debug symbols later, only for the release build.
-std=c99
By default gcc compiles in its own extended dialect — typically
something newer than C99, with GCC-specific extras mixed in.
-std=c99 tells it to enforce the 1999 C standard exactly and
reject anything beyond it. Code that compiles under -std=c99
will compile the same way on any conforming toolchain, including
the cross-compilers we use in the r-tier.
We will add it to CFLAGS in the Makefile on page 06. The
sanitiser rebuilds from page 05 onward also carry it.
Optimisation: -O0, -O2, -O3, -Og
gcc can rearrange and rewrite your code to make the binary
faster, at the cost of making it harder to debug — variables
disappear into registers, lines get reordered, branches get
predicted. The flag is -O followed by a level:
-O0is the default if you do not say. No optimisation. Slowest binary, easiest to debug.-O2is what most release builds use. Aggressive optimisation that does not bloat the binary unnecessarily.-O3is more aggressive still. Sometimes faster, sometimes not.-Ogis "optimise for debugging" — a middle ground that does some safe optimisations while keeping the binary debuggable.
During development we use -O0 (implicit, no flag) so debugger
output lines up exactly with source. Release builds use -O2. We
will not need release builds in this chapter.
-I, -L, -l
These three are about external code. You will not need them yet
— sort only uses the standard library, which gcc finds without
help — but they show up the moment a project pulls in a third-party
library, so they are worth meeting now.
-I pathaddspathto the list of directoriesgccsearches for header files. If you#include "foo.h"andfoo.hlives in~/code/include/, you compile with-I ~/code/include.-L pathdoes the same for library files (the compiled artefacts the linker pulls in).-l nametells the linker to link againstlib<name>.so(orlib<name>.a). For example-lmlinks the math library.
If you ever see a build error like cannot find -lfoo or no such file: bar.h, one of these three flags is missing.
Recompiling sort
With everything together:
gcc -Wall -Wextra -g sort.c -o sort
./sort test.txtYou should still see the same sorted output, with no warnings. The program looks correct. It is not.
The next three pages turn each of gdb, valgrind, and the
sanitisers loose on it. One bug per tool.