D
David Resnick
We recently had a bug that was (effectively) something like this
if ( a < 0 && a > someConstantValue )
{
/* do some error handling */
}
The && meant to be ||, somehow slipped through the cracks during code
review and was an error case that never actually got tested. gcc
doesn't object to the above with -Wall -Wextra. I'm wondering if
there are options with gcc or for that matter other compilers that
might notice this sort of always false condition, which they can know
at compile time always true/always false assuming a is not volatile.
I realize that this would need special casing to not warn on the cases
like if (0), while (0), while (1) that are rather heavily used, and
maybe this would conflict with other common usage. gcc does warn on
some comparisons it can notice by static analysis are always false
based on type range, which feels a bit related, such as:
temp(861)$ cat foo.c
#include <stdio.h>
int main(void)
{
const unsigned char a = 5;
if ( a < 0 && a > 255)
{
printf("Absolutely, totally, and in all other ways
inconceivable.\n");
}
return 0;
}
temp(862)$ gcc -o foo -Wall -pedantic -Wextra -O2 foo
foo.c: In function 'main':
foo.c:5: warning: comparison is always false due to limited range of
data type
foo.c:5: warning: comparison is always false due to limited range of
data type
It makes the two warnings the same whether it is && or ||.
gcc also generates the warning here, where the overall condition is in
fact always true, it is based on the individual comparison not the
overall expression...
const unsigned char a = 5;
if ( a < 0 || a == 5)
{
printf("You keep using that word. I do not think it means
what you think it means.\n");
}
Any thoughts? Just too complicated in practice? Worth raising to gcc/
others?
if ( a < 0 && a > someConstantValue )
{
/* do some error handling */
}
The && meant to be ||, somehow slipped through the cracks during code
review and was an error case that never actually got tested. gcc
doesn't object to the above with -Wall -Wextra. I'm wondering if
there are options with gcc or for that matter other compilers that
might notice this sort of always false condition, which they can know
at compile time always true/always false assuming a is not volatile.
I realize that this would need special casing to not warn on the cases
like if (0), while (0), while (1) that are rather heavily used, and
maybe this would conflict with other common usage. gcc does warn on
some comparisons it can notice by static analysis are always false
based on type range, which feels a bit related, such as:
temp(861)$ cat foo.c
#include <stdio.h>
int main(void)
{
const unsigned char a = 5;
if ( a < 0 && a > 255)
{
printf("Absolutely, totally, and in all other ways
inconceivable.\n");
}
return 0;
}
temp(862)$ gcc -o foo -Wall -pedantic -Wextra -O2 foo
foo.c: In function 'main':
foo.c:5: warning: comparison is always false due to limited range of
data type
foo.c:5: warning: comparison is always false due to limited range of
data type
It makes the two warnings the same whether it is && or ||.
gcc also generates the warning here, where the overall condition is in
fact always true, it is based on the individual comparison not the
overall expression...
const unsigned char a = 5;
if ( a < 0 || a == 5)
{
printf("You keep using that word. I do not think it means
what you think it means.\n");
}
Any thoughts? Just too complicated in practice? Worth raising to gcc/
others?