Even if you've fixed every compiler error and linker error your compiler
gives
you, it may still give you "warnings" (the cheeky bastard). These
warnings
won't keep your code from compiling (unless you ask the compiler to
treat
warnings as errors), and you might be tempted to just ignore them.
There are,
however, some good reasons not to do so. In doing so, I'll also cover
some
specific examples of the types of warnings you might face, what they
mean, and
how to fix them.
Catch Bugs Before Testing
The great thing about compiler warnings is that they are often
indicators of
future bugs that you would otherwise see only at runtime. For instance,
if you
see your compiler complaining about an "assignment in conditional" then
it
might mean that you've written
if ( x = 5 ) //uh oh, x = 5 will evaluate to the value 5, which is always true
{
/* ... */
}
when what you really meant was
if ( x == 5 )
{
/* ... */
}
You might have figured this out when your code always entered the if
statement,
but you wouldn't have known exactly why it was doing that. Maybe x
wasn't
being set properly (for instance, it might have been uninitialized). A
scarier
situation is one in which you never actually tested that branch of the
if
statement when x wasn't equal to five. This means that you would have a
bug
sitting in your code after you thought it was done. So the compiler
warning
both tells you exactly what is wrong and alerts you to a problem you
might
never have found!
Just for fun, here's an even more compelling example of when you'd have
trouble finding the bug during testing.
if ( x = 0 )
{
std::cout << "x is zero!";
}
Since x would generally not equal zero, the if statement generally
wouldn't be
expected to execute. Now, since x = 0 evaluates to false, this
statement will
always be false. If you never test the situation where x actually is 0,
then
you won't notice that the body of the if statement never executes.
Catch Bugs that are Hard to Find in Testing
Compilers will always warn you about things that might be difficult to
find
during testing. For example, your compiler can warn you that you are
using an
uninitialized variable; this can be hard to find in testing if you
declare your
variable far from the spot you first use it. (Note that "using" an
uninitialized variable simply means getting its value; it's perfectly
fine to
initialize it. In fact, that's the solution to the problem.)
Another insidious bug is forgetting to return a value from a function.
Sometimes this can be tricky to spot even once your compiler points it
out.
This migh thappen when your function has multiple paths through the code
and
most of them return a value; it's left up ot you to find the one that
doesn't.
int searchArray(int to_search[], int len, int to_find)
{
int i;
for( i = 0; i < len; ++i )
{
if ( to_search[i] == to_find )
{
return i;
}
}
}
Notice that most of the time, this function will return a value. It's
only
when the value isn't in the array that you wouldn't find it. This bug
can be
hard to spot in later testing both because this may be an uncommon
occurence
and because the results of not returning a value when one is expected
can be
extremely weird. For instance, you might get a valid index of the
array, or
you might get something way too big (more likely). In either case, the
problems in the running program wouldn't appear in the function at all.
Lessons to Take Away
While you've picked up a few tips for combatting compiler warnings, the
real
message here should be the mindset you should have--catch bugs as early
as
possible, and take advantage of your tools, like the compiler, that tell
you
exactly where problems are before you discover something mysterious
during
testing. Sometimes there may be no need for you to set your compiler to
fail
on any warnings, but if you use automated scripts for building your
program or
tend to ignore the compiler unless it fails, then this might be a useful
thing
to do. You'll have to look at your compiler documentation for exactly
how to
set this up; on gcc and g++, all you need to use is the -Werror flag
("treat
warnings as errors").
Furthermore, if you don't understand what a compiler warning means, it's
probably best to trust that the compiler is telling you something
valuable.
I've had experiences where I was convinced that my code was correct and
wasn't
entirely sure what the compiler could be complaining about. But after
investigating my compiler's complaints, I realized I had made a subtle
mistake
in a boolean expression that would have been nearly impossible to hone
in on
when debugging--it was much easier to catch the mistake while the code
was
fresh in my mind code rather than hours or possibly days later when I
might
(with luck) have found the bug due to the mistake.
Related articles
阅读(691) | 评论(0) | 转发(0) |