Re: macrotab.c -Werror

Jim Blandy
2002-05-14T19:55:29Z

Daniel Berlin <dberlin@dberlin.org> writes:
> It's an obvious false positive (!best will be true the first time through,
> meaning the only time we check best_depth, it's already been set at
> least once).
>
> Here, you can't just initialize best_depth to 0, you have to initialize it
> to either INT_MAX, or inclusion_depth (result).
>
> Sucks.

You're going too fast. Here's the whole loop, for the sake of
discussion:

/* It's not us. Try all our children, and return the lowest. */
{
struct macro_source_file *child;
struct macro_source_file *best = 0;
int best_depth;

for (child = source->includes; child; child = child->next_included)
{
struct macro_source_file *result
= macro_lookup_inclusion (child, name);

if (result)
{
int result_depth = inclusion_depth (result);

if (! best || result_depth < best_depth)
{
best = result;
best_depth = result_depth;
}
}
}

The only reference to `best_depth''s value is in the right operand of
`||'. That operand will never be evaluated unless `best' is non-zero.
But `best' is initially zero, and is only assigned along with
`best_depth'. So `best_depth''s initial value is never used. This
means:
- the original code is correct (although the compiler doesn't figure
that out), and
- you can initialize it to anything you want, since its initial value
is never used.

I don't actually know how many unnecessary initializations there are
in GDB to silence the compiler, but it's my impression that the
compiler's false positive rate for `var might be used uninitialized'
warnings is low enough that it's still a useful sanity check. So I'm
happy to add a few unnecessary initializations.

What sucks (a bit) is that every one of those unnecessary
initializations does end up generating code --- if the compiler could
tell it was unnecessary, it wouldn't have printed the warning!