Here are mine:
-Wextraand-Wall: essential.-Wfloat-equal: useful because usually testing floating-point numbers for equality is bad.-Wundef: warn if an uninitialized identifier is evaluated in an#ifdirective.-Wshadow: warn whenever a local variable shadows another local variable, parameter or global variable or whenever a built-in function is shadowed.-Wpointer-arith: warn if anything depends upon the size of a function or ofvoid.-Wcast-align: warn whenever a pointer is cast such that the required alignment of the target is increased. For example, warn if achar *is cast to anint *on machines where integers can only be accessed at two- or four-byte boundaries.-Wstrict-prototypes: warn if a function is declared or defined without specifying the argument types.-Wstrict-overflow=5: warns about cases where the compiler optimizes based on the assumption that signed overflow does not occur. (The value 5 may be too strict, see the manual page.)-Wwrite-strings: give string constants the typeconst char[length]so that copying the address of one into a non-const char *pointer will get a warning.-Waggregate-return: warn if any functions that return structures or unions are defined or called.-Wcast-qual: warn whenever a pointer is cast to remove a type qualifier from the target type*.-Wswitch-default: warn whenever aswitchstatement does not have adefaultcase*.-Wswitch-enum: warn whenever aswitchstatement has an index of enumerated type and lacks acasefor one or more of the named codes of that enumeration*.-Wconversion: warn for implicit conversions that may alter a value*.-Wunreachable-code: warn if the compiler detects that code will never be executed*.
Those marked * sometimes give too many spurious warnings, so I use them on as-needed basis.
Answer from Alok Singhal on Stack OverflowVideos
Hi,
I'm a beginner, barely scratching the surface of C at the moment. Question is, what flags do I choose for compilation? There are some "basic" like -Wall, -W, -pedantic, -ansi, -std=. GCC documentation has a ton of different flags.
Should I learn Make or CMake early to avoid retyping flags every time to compile my source files?Any help, advice are greatly appreciated.
Edit: thank you, guys. Lots of useful and interesting information. You're awesome!
Here are mine:
-Wextraand-Wall: essential.-Wfloat-equal: useful because usually testing floating-point numbers for equality is bad.-Wundef: warn if an uninitialized identifier is evaluated in an#ifdirective.-Wshadow: warn whenever a local variable shadows another local variable, parameter or global variable or whenever a built-in function is shadowed.-Wpointer-arith: warn if anything depends upon the size of a function or ofvoid.-Wcast-align: warn whenever a pointer is cast such that the required alignment of the target is increased. For example, warn if achar *is cast to anint *on machines where integers can only be accessed at two- or four-byte boundaries.-Wstrict-prototypes: warn if a function is declared or defined without specifying the argument types.-Wstrict-overflow=5: warns about cases where the compiler optimizes based on the assumption that signed overflow does not occur. (The value 5 may be too strict, see the manual page.)-Wwrite-strings: give string constants the typeconst char[length]so that copying the address of one into a non-const char *pointer will get a warning.-Waggregate-return: warn if any functions that return structures or unions are defined or called.-Wcast-qual: warn whenever a pointer is cast to remove a type qualifier from the target type*.-Wswitch-default: warn whenever aswitchstatement does not have adefaultcase*.-Wswitch-enum: warn whenever aswitchstatement has an index of enumerated type and lacks acasefor one or more of the named codes of that enumeration*.-Wconversion: warn for implicit conversions that may alter a value*.-Wunreachable-code: warn if the compiler detects that code will never be executed*.
Those marked * sometimes give too many spurious warnings, so I use them on as-needed basis.
Several of the -f code generation options are interesting:
-fverbose-asmis useful if you're compiling with-Sto examine the assembly output - it adds some informative comments.-finstrument-functionsadds code to call user-supplied profiling functions at every function entry and exit point.--coverageinstruments the branches and calls in the program and creates a coverage notes file, so that when the program is run coverage data is produced that can be formatted by thegcovprogram to help analysing test coverage.-fsanitize={address,thread,undefined}enables the AddressSanitizer, ThreadSanitizer and UndefinedBehaviorSanitizer code sanitizers, respectively. These instrument the program to check for various sorts of errors at runtime.
Previously this answer also mentioned -ftrapv, however this functionality has been superseded by -fsanitize=signed-integer-overflow which is one of the sanitizers enabled by -fsanitize=undefined.
You don't need any environment variables, just pass in right cflags and ldflags that SDL2 wants you to use:
gcc main.c `pkg-config --cflags sdl2` -o main `pkg-config --libs sdl2`
or either
gcc main.c `sdl2-config --cflags` -o main `sdl2-config --libs`
Remember: CFLAGS come before LDFLAGS, and LDFLAGS (and library specification with -l) comes last.
SDL2 comes with sdl2-config script preinstalled. You will need to set your PATH to the directory where it resides to call it successfully:
export PATH=/opt/SDL2/bin:$PATH
If you will run every of *-config commands directly, you will see that they just output right cflags and ldflags for you. That's because the libraries that employ these scripts usually bigger than to specify single -I/-L argument, and it is not portable to specify single -I/-L arguments for them, because number of such arguments can be increased in future.
And you should not install every package in it's own directory. Install everything into /usr/local for example, then you will not need even to specify anything (most distros point you to /usr/local automatically).
As can be seen in the Catalogue of Built-In Rules:
Linking a single object file
nis made automatically fromn.oby running the linker (usually calledld) via the C compiler. The precise recipe used is:$(CC) $(LDFLAGS) n.o $(LOADLIBES) $(LDLIBS)
and Variables Used by Implicit Rules:
LDFLAGS
Extra flags to give to compilers when they are supposed to invoke the linker,
ld, such as-L. Libraries (-lfoo) should be added to the LDLIBS variable instead.
So in this case -lSDL2 should be set or added to LDLIBS, not LDFLAGS.