views:

240

answers:

4

I'm just digging into the gcc manual and some things are still unclear to me:

  1. When specifying a std, should I always use -pedantic in conjunction?
  2. When using -g, it the standard level sufficient or should I specify level 3, i.e. -g3?
  3. Is it good practice to use -Werror to promote all warnings to errors and -pedantic-errors to promote all pedantic warnings to errors?
+3  A: 

I like to use -Wall -Wextra for C++. However, if -Wextra reports warnings on headers of libraries I use I usually drop it.

Eddy Pronk
What do you drop – `-Wextra` or the dumb library header? (Hint: should be the latter! ;-))
Konrad Rudolph
Use -isystem instead of -I to specify library header path.
Laurynas Biveinis
-Wextra tends to have a much higher rate of false positives than -Wall is the issue though.
Mark B
+7  A: 

All of these are matters of opinion and/or dependent on your codebase and programming practices. I always compile with -Wall and -pedantic, I don't care whether things are flagged as errors or warnings, so I never use -Werror, and I very rarely debug code using the debugger - when I do, -g suffices. Someone else might come up with a completely different answer.

anon
+3  A: 

If you are writing a library, please do make sure that a simple program like

#include <yourlib.h>
int main() {
    return 0;
}

compiles without any warnings whatsoever even when the compiler is running in the most pedantic mode with all optional warnings enabled.

If you are writing an application, your code throwing warnings left and right is just your application's problem. With a library's public header file, however, everybody who later uses that library will be forced to ignore or endure the warnings your code is causing.

So please check that your library headers compile without warnings, if possible in multiple compiler modes:

$ gcc -Wall -Wextra -Werror -std=c99   -pedantic
$ gcc -Wall -Wextra -Werror -std=gnu99 -pedantic
$ gcc -Wall -Wextra -Werror -std=c89   -pedantic
$ gcc -Wall -Wextra -Werror -std=gnu89 -pedantic
ndim
Some C99 code is not valid C89 code - that doesn't make it bad code. Portability between the two is only required if such portability it is actually a stated aim of the project.
anon
+1 I read about the -Wextra flag but didn't find that too useful but as nearly everyone recommends it, it seem's to be useful. But why? What is it actually good for?
Helper Method
@Neil: For applications, yes. However, a library's public API header file should not impose C99 or C89 upon the program which includes it. Otherwise, one library needs C89 (but not C99) and the other needs C99 (but not C89) and as an application writer interfacing to both libraries I am screwed.
ndim
anon
@Neil: As far as I can tell, today's code landscape is predominantly C89 and C99, so I would say supporting those two with your library API makes sense.
ndim
+3  A: 

These are all highly subjective. Here are my opinions:

  1. Your use of -pedantic shouldn't be tied to your use of -std=foo. Use -pedantic if you want pedantic errors messages; if you're using -pedantic, you'll probably also want -Wall and -Wextra, since your goal is usually to catch all possible missteps, no matter how minor. Note that -pedantic will not catch all possible warnings, only the warnings that the ISO C standard requires a diagnostic for.

  2. I've always found level 2 (the default with -g) to be good enough for my purposes. Level 3 also includes information about all macro definitions in your program, but that's only useful if your debugger supports macro expansions; mine does not (GNU gdb 6.3.50-20050815 (Apple version gdb-696)). I don't know what else level 3 includes that level 2 does not.

  3. That depends. If your goal is to make the most portable, most standards-compliant code, then yes, I'd highly recommend always using -Werror and -pedantic-error (along with -Wall and -Wextra), especially when starting new projects. However, if you're starting with a large codebase, turning on these options will likely give you tons of harmless, spurious errors, especially for things like signed/unsigned mismatch and implicit conversions between various types. It will take you a very long time to fix up a codebase to remove these errors, so I wouldn't recommend it.

    If you're doing a quick throwaway project, don't bother, since these will only slow you down.

    If you're working on a library or something that will get open sourced, then please do turn these on. Your users will greatly appreciate the fact that your code does not produce errors or warnings. Also take ndim's advice into account.

Adam Rosenfield

related questions