comparison is always false

Discussion in 'C++' started by John Ratliff, Feb 1, 2007.

  1. John Ratliff

    John Ratliff Guest

    "comparison is always false due to limited range of data type"

    I get this warning with g++ when I compile some code and I'm not quite
    sure I understand it.

    I have a small file that I've read into a memory buffer. It is defined
    char sram[0x2000];

    I need to check for a specific value within this buffer.

    However, when I do

    if (sram[36] == 0xC8) {
    // blah blah
    }

    I get the warning.

    What specifically is wrong with this? Is it a signedness issue? When I
    use static_cast<unsigned char>(sram[36]) instead, I stop getting the
    warning. Is this a correct solution, or am I simply silencing the error
    without fixing the problem?

    Thanks,

    --John Ratliff
     
    John Ratliff, Feb 1, 2007
    #1
    1. Advertising

  2. John Ratliff

    Ivan Novick Guest

    On Feb 1, 12:25 am, John Ratliff <> wrote:
    > "comparison is always false due to limited range of data type"
    >
    > I get this warning with g++ when I compile some code and I'm not quite
    > sure I understand it.
    >
    > I have a small file that I've read into a memory buffer. It is defined
    > char sram[0x2000];
    >
    > I need to check for a specific value within this buffer.
    >
    > However, when I do
    >
    > if (sram[36] == 0xC8) {
    > // blah blah
    >
    > }
    >
    > I get the warning.
    >

    I believe that ascii characters can be no bigger than 0x7F, so the
    comparison will always be false because there are no characters 0xC8.
    Are you putting ASCII data into the buffer or binary data?
    ---
    Ivan
    http://www.0x4849.net
     
    Ivan Novick, Feb 1, 2007
    #2
    1. Advertising

  3. John Ratliff

    Kai-Uwe Bux Guest

    John Ratliff wrote:

    > "comparison is always false due to limited range of data type"
    >
    > I get this warning with g++ when I compile some code and I'm not quite
    > sure I understand it.
    >
    > I have a small file that I've read into a memory buffer. It is defined
    > char sram[0x2000];
    >
    > I need to check for a specific value within this buffer.
    >
    > However, when I do
    >
    > if (sram[36] == 0xC8) {
    > // blah blah
    > }
    >
    > I get the warning.
    >
    > What specifically is wrong with this? Is it a signedness issue?


    Most likely.

    > When I
    > use static_cast<unsigned char>(sram[36]) instead, I stop getting the
    > warning. Is this a correct solution, or am I simply silencing the error
    > without fixing the problem?


    If you are willing to treat the buffer as a buffer of unsigned char, why not
    declare

    unsigned char sram[0x2000];

    right away?


    Best

    Kai-Uwe Bux
     
    Kai-Uwe Bux, Feb 1, 2007
    #3
  4. On Feb 1, 9:25 am, John Ratliff <> wrote:
    > "comparison is always false due to limited range of data type"
    >
    > I get this warning with g++ when I compile some code and I'm not quite
    > sure I understand it.
    >
    > I have a small file that I've read into a memory buffer. It is defined
    > char sram[0x2000];
    >
    > I need to check for a specific value within this buffer.
    >
    > However, when I do
    >
    > if (sram[36] == 0xC8) {
    > // blah blah
    >
    > }
    >
    > I get the warning.
    >
    > What specifically is wrong with this? Is it a signedness issue?


    Yes, the char is (most probably) 8 bits signed which makes the value
    range -128..127 IIRC. And 0xC8 == 200, which as you can see is not in
    that range, thus false. When dealing with binary data you should
    almost always use unsigned char.

    --
    Erik Wikström
     
    =?iso-8859-1?q?Erik_Wikstr=F6m?=, Feb 1, 2007
    #4
  5. John Ratliff

    John Ratliff Guest

    >>
    >> What specifically is wrong with this? Is it a signedness issue?

    >
    > Yes, the char is (most probably) 8 bits signed which makes the value
    > range -128..127 IIRC. And 0xC8 == 200, which as you can see is not in
    > that range, thus false. When dealing with binary data you should
    > almost always use unsigned char.


    That's what I thought, but I assumed the compiler would treat C8 as a
    negative signed value, but perhaps it doesn't.

    I could have used an unsigned char array, but it just requires casting
    in different places. I thought using a signed char array would reduce
    the number of explicit casts required. Binary file reading and some of
    my string methods use signed chars.

    Thanks,

    --John Ratliff
     
    John Ratliff, Feb 1, 2007
    #5
  6. John Ratliff

    Ron Natalie Guest

    John Ratliff wrote:
    >>>
    >>> What specifically is wrong with this? Is it a signedness issue?

    >>
    >> Yes, the char is (most probably) 8 bits signed which makes the value
    >> range -128..127 IIRC. And 0xC8 == 200, which as you can see is not in
    >> that range, thus false. When dealing with binary data you should
    >> almost always use unsigned char.

    >
    > That's what I thought, but I assumed the compiler would treat C8 as a
    > negative signed value, but perhaps it doesn't.


    Nope, 0xC8 is a 200 decimal and is of type integer. When an int is
    compared to a char, the char is converted to the int and not the
    other way around (usual arithmatic conversions).


    You could do
    if (foo[32] == static_cast<char>(0xC8)) ...
     
    Ron Natalie, Feb 1, 2007
    #6
  7. John Ratliff

    Heinz Ozwirk Guest

    "John Ratliff" <> schrieb im Newsbeitrag
    news:...
    >>>
    >>> What specifically is wrong with this? Is it a signedness issue?

    >>
    >> Yes, the char is (most probably) 8 bits signed which makes the value
    >> range -128..127 IIRC. And 0xC8 == 200, which as you can see is not in
    >> that range, thus false. When dealing with binary data you should
    >> almost always use unsigned char.

    >
    > That's what I thought, but I assumed the compiler would treat C8 as a
    > negative signed value, but perhaps it doesn't.


    It doesn't. Octal and hexadecimal literals are usually treated as as the
    first type of int, unsigned int, long or unsigned long, which is large
    enough to hold them.

    > I could have used an unsigned char array, but it just requires casting in
    > different places. I thought using a signed char array would reduce the
    > number of explicit casts required. Binary file reading and some of my
    > string methods use signed chars.


    If you want to compare a char variable with a constant value you should use
    a char literal, '\xC8' in your case, or, even better, a named constant like
    const char foo = '\xC8';.

    HTH
    Heinz
     
    Heinz Ozwirk, Feb 1, 2007
    #7
  8. John Ratliff

    John Ratliff Guest

    Heinz Ozwirk wrote:
    > "John Ratliff" <> schrieb im Newsbeitrag
    > news:...
    >>>> What specifically is wrong with this? Is it a signedness issue?
    >>> Yes, the char is (most probably) 8 bits signed which makes the value
    >>> range -128..127 IIRC. And 0xC8 == 200, which as you can see is not in
    >>> that range, thus false. When dealing with binary data you should
    >>> almost always use unsigned char.

    >> That's what I thought, but I assumed the compiler would treat C8 as a
    >> negative signed value, but perhaps it doesn't.

    >
    > It doesn't. Octal and hexadecimal literals are usually treated as as the
    > first type of int, unsigned int, long or unsigned long, which is large
    > enough to hold them.
    >
    >> I could have used an unsigned char array, but it just requires casting in
    >> different places. I thought using a signed char array would reduce the
    >> number of explicit casts required. Binary file reading and some of my
    >> string methods use signed chars.

    >
    > If you want to compare a char variable with a constant value you should use
    > a char literal, '\xC8' in your case, or, even better, a named constant like
    > const char foo = '\xC8';.


    That's a perfect solution. Thanks.

    So now I have

    const char MAGIC_NUMBER = '\xC8';

    if (sram[offset] == MAGIC_NUMBER) {
    // ...
    }

    No more required cast, and no compiler warnings.

    --John Ratliff
     
    John Ratliff, Feb 2, 2007
    #8
  9. John Ratliff

    Old Wolf Guest

    On Feb 2, 8:44 am, Ron Natalie <> wrote:
    > You could do
    > if (foo[32] == static_cast<char>(0xC8)) ...


    This causes implementation-defined behaviour
    if 0xC8 is outside of the range of char.
     
    Old Wolf, Feb 4, 2007
    #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. André
    Replies:
    3
    Views:
    1,596
  2. Dave
    Replies:
    2
    Views:
    746
    Randy Howard
    Feb 26, 2005
  3. Rajarshi

    0 == False but [] != False?

    Rajarshi, May 24, 2007, in forum: Python
    Replies:
    20
    Views:
    709
    Erik Max Francis
    May 30, 2007
  4. DJ
    Replies:
    3
    Views:
    935
  5. Nachy
    Replies:
    11
    Views:
    582
    Kaz Kylheku
    Mar 14, 2012
Loading...

Share This Page