do any compilers notice/warn on always false expressions used as conditions

Discussion in 'C Programming' started by David Resnick, Nov 18, 2010.

  1. 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?
     
    David Resnick, Nov 18, 2010
    #1
    1. Advertising

  2. David Resnick

    Bill Davy Guest

    "David Resnick" <> wrote in message
    news:...
    > 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?



    PC-Lint would certainly point out "(unsigned) < 0" is questionable. Their
    user forums are pretty good (http://www.gimpel.com/).
    They have reasonable value tracking ideas which help a lot.

    Bill
     
    Bill Davy, Nov 18, 2010
    #2
    1. Advertising

  3. David Resnick

    Ike Naar Guest

    Re: do any compilers notice/warn on always false expressions usedas conditions

    On 2010-11-18, David Resnick <> wrote:
    > const unsigned char a = 5;
    > if ( a < 0 && a > 255)
    > [...]
    > foo.c:5: warning: comparison is always false due to limited range of
    > data type


    Apparently the warning is about the ``a < 0'' part.
    ``a'' has an unsigned type so it cannot be less than zero.
     
    Ike Naar, Nov 18, 2010
    #3
  4. David Resnick

    Chris H Guest

    In message <
    s.com>, David Resnick <> writes
    >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.


    It's not a compiler problem. A compiler is a translator. If the code is
    legal syntax the compiler is happy.

    What you need is static analysis.


    --
    \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
    \/\/\/\/\ Chris Hills Staffs England /\/\/\/\/
    \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
     
    Chris H, Nov 18, 2010
    #4
  5. On Nov 18, 10:16 am, Chris H <> wrote:
    > It's not a compiler problem.  A compiler is a translator. If the code is
    > legal syntax the compiler is happy.
    >
    > What you need is static analysis.
    >


    Yes, sure. But gcc does notice superficially similar classes of
    problems. Just was wondering if there was any precedent (or
    specifically gcc way) that the compiler might notice this. For
    example, the optimizer might quite reasonably detect this and remove
    the branching entirely if the condition at compile time can be
    determined to be always false/always true, in which case there COULD
    be an associated warning...

    -David
     
    David Resnick, Nov 18, 2010
    #5
  6. David Resnick

    Chris H Guest

    In message <
    s.com>, David Resnick <> writes
    >On Nov 18, 10:16 am, Chris H <> wrote:
    >> It's not a compiler problem.  A compiler is a translator. If the code is
    >> legal syntax the compiler is happy.
    >>
    >> What you need is static analysis.
    >>

    >
    >Yes, sure. But gcc does notice superficially similar classes of
    >problems.


    You said it: "superficially similar".

    That is why all C code should be statically analysed. It was always
    intended that Lint should be part of the compile chain to stop "legal
    but dubious constructs"


    --
    \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
    \/\/\/\/\ Chris Hills Staffs England /\/\/\/\/
    \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
     
    Chris H, Nov 18, 2010
    #6
  7. David Resnick

    Willem Guest

    Re: do any compilers notice/warn on always false expressions usedas conditions

    David Resnick wrote:
    ) 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

    Does -Wextra include -Wunreachable-code ?
    Are you using optimization ?


    SaSW, Willem
    --
    Disclaimer: I am in no way responsible for any of the statements
    made in the above text. For all I know I might be
    drugged or something..
    No I'm not paranoid. You all think I'm paranoid, don't you !
    #EOT
     
    Willem, Nov 18, 2010
    #7
  8. On Nov 18, 12:29 pm, Willem <> wrote:
    > David Resnick wrote:
    >
    > ) 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
    >
    > Does -Wextra include -Wunreachable-code ?
    > Are you using optimization ?



    Just what I was looking for, thanks. That flag makes gcc notice.
    example:

    temp(926)$ cat foo.c
    #include <stdio.h>
    #include <stdlib.h>
    int main(void)
    {
    int a = rand();
    if ( a < 0 && a > 5)
    {
    printf("inconceivable\n");
    }

    return 0;
    }
    temp(927)$ gcc -o foo -Wall -pedantic -Wextra -Wunreachable-code -O2
    foo.c
    foo.c: In function 'main':
    foo.c:8: warning: will never be executed

    Note that -Wextra alone doesn't give you that...

    -David
     
    David Resnick, Nov 18, 2010
    #8
  9. David Resnick

    robin Guest

    "David Resnick" <> wrote in message
    news:...
    | 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)

    if 'a' is unsigned char, how it is going to be negative?
    Greater than 255?
     
    robin, Nov 18, 2010
    #9
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    65
    Views:
    1,191
    Rob Thorpe
    Aug 25, 2005
  2. geletine

    commercial c compilers vs free c compilers

    geletine, Jul 2, 2006, in forum: C Programming
    Replies:
    33
    Views:
    1,348
  3. Alfred Z. Newmane
    Replies:
    11
    Views:
    515
    CBFalconer
    Jun 27, 2005
  4. Robin Wenger
    Replies:
    3
    Views:
    405
    Arne Vajhøj
    Jan 20, 2011
  5. Alex Rast
    Replies:
    6
    Views:
    176
    Dr John Stockton
    Feb 29, 2004
Loading...

Share This Page