In the past I\'ve worked with -Wall and other switches for gcc to eliminate every compiler warning for projects I\'ve been involved in. Similarly, in Perl, I always program wit
Is this worth a programmer's time? Will a project really be much better if you track down every single compiler warning?
Yes. Even the trivial ones about sign mismatch can have profound impact on code generation and optimizations.
I agree with all the answers that say "fix them all", but I'd still like to present an opposing view:
There are legacy systems where some (many or all) components are without a dedicated maintainer and large parts of the system are basically unknown. Fixing compiler warnings in such unknown code can take a considerable amount of code (since for each warning the code together with its context needs to be understood) and introduces a possible source of errors (some code depends on undefined behaviour). And since such legacy systems rarely have extensive test coverage you can't even rely on the tests to notify you of regressions.
Your example is a perfect illustration why warnings shouldn't be ignored. void main(void)
is an invalid prototype (but int main(void)
works!)) and your code may break on some compilers. Your compiler was nice enough to point this out.
I've found that almost every warning actually pointed to a real problem, even if I failed to understand the cause at the time. Basically, I always did something and intended something else. The effect might have been achieved anyway, but only by pure coincidence.
Treat warnings as errors. Exceptions exist (there's one in the VB.NET compiler concerning uninitialized value types) but are exceedingly rare. And if you ever stumble upon one of these exceptions, you'll know it.
There are two compliant prototypes for main in C.
int main(void)
and
int main(int argc, char **argv)
void main(void)
is not technically correct, although it may be supported by some compilers as an extension to the standard.
So, in your particular case, you can use a short declaration of main
and, if compliant, it won't trigger the warning.
You should always try to have no warnings come up on a compile. That way, new warnings get attention. (My most frustrating experience ever with this was the AIX C++ compiler back in 2002, which spat out hundreds of warnings for code that wasn't even heavily templated.)
Know what each warning means. In your case, you should have typed the standard int main()
rather than the incorrect void main(void)
or the clumsier int main(int argc, char **argv)
. Eliminate what you can, and suppress the warnings you have deemed acceptable.
You may not want to fix every warning. As saua says, there are legacy systems where fixing warnings is downright dangerous, and complex systems like CGAL where you don't want to muck with the code either. In converting our apps to run under 64 bits, I found cases where I could eliminate a warning only with a cast, which would have potentially caused other problems. We suppressed that warning.
Yes. Even the trivial ones are worth fixing. Here's why. Some, like the example of main you mention, probably aren't worth fixing on their own, but they are in aggregate. Most compiler warnings will save you direct pain in the long term. They are bugs waiting to happen (or even happening now). In order to find those, you need an easy way to notice them. If you fix all of the warnings, then each new warning is a red flag and easy to notice. If you fix all of the critical ones but leave some like the "main" issue alone, you will miss the new critical ones.
Which is easier to remember? That any warning needs to be fixed or that you had 23 irrelevant warnings in this code base yesterday and so if you see 24 you need to go take a look?
In the code base I work on we tell the compiler to generate errors on all warnings. This forces us to fix them and keeps the code in much better shape. If there's ever a warning that truly isn't worth fixing, there is always #pragma to make it disappear. That way you still have a bright line for failure.