question 'bout less-than and cast to unsigned

Discussion in 'C++' started by .rhavin grobert, Nov 26, 2008.

  1. typedef unsigned int UINT;

    foo(-1);

    void foo(int iOffset)
    {
    if ((UINT)iOffset < 3)
    return;
    // why do i get here?
    }

    on my vc6 i can read in debugger that iOffset is (as expected)
    0xffffffff. shouldnt ((UINT)iOffset < 3) convert to (1<3) and
    therefore the 'return' be called?
     
    .rhavin grobert, Nov 26, 2008
    #1
    1. Advertising

  2. ..rhavin grobert schrieb:
    > typedef unsigned int UINT;
    >
    > foo(-1);
    >
    > void foo(int iOffset)
    > {
    > if ((UINT)iOffset < 3)
    > return;
    > // why do i get here?
    > }
    >
    > on my vc6 i can read in debugger that iOffset is (as expected)
    > 0xffffffff. shouldnt ((UINT)iOffset < 3) convert to (1<3) and
    > therefore the 'return' be called?


    You said yourself: iOffset ist 0xffffffff, which is not less than 3,
    isn't it?
    Casting a negativ number n to an unsigned type gives you 2**(number of
    bits) + n, which is 0x100000000 - 1, in your case.

    Also, VC6 is quite old and contains many bugs. There are newer versions
    available for free on the Microsoft website.

    --
    Thomas
     
    Thomas J. Gritzan, Nov 26, 2008
    #2
    1. Advertising

  3. .rhavin grobert

    Joe Smith Guest

    ".rhavin grobert" <> wrote in message
    news:...
    > typedef unsigned int UINT;
    >
    > foo(-1);
    >
    > void foo(int iOffset)
    > {
    > if ((UINT)iOffset < 3)
    > return;
    > // why do i get here?
    > }
    >
    > on my vc6 i can read in debugger that iOffset is (as expected)
    > 0xffffffff. shouldnt ((UINT)iOffset < 3) convert to (1<3) and
    > therefore the 'return' be called?


    Why do you expect -1 to become 1 on a cast to unsigned. I would expect it to
    become
    4294967295 considering that you are clearly on a platform that uses 2's
    complement integers, which is emphatically not less than 3. Perhaps you are
    looking for something more like std::abs?
     
    Joe Smith, Nov 26, 2008
    #3
  4. .rhavin grobert

    maverik Guest

    On Nov 26, 6:20 pm, ".rhavin grobert" <> wrote:
    > typedef unsigned int UINT;
    >
    > foo(-1);
    >
    > void foo(int iOffset)
    > {
    >         if ((UINT)iOffset < 3)
    >                 return;
    >         // why do i get here?
    >
    > }
    >
    > on my vc6 i can read in debugger that iOffset is (as expected)
    > 0xffffffff. shouldnt ((UINT)iOffset < 3) convert to (1<3) and
    > therefore the 'return' be called?


    Type cast goes before compare, so you get such a result
    (see Bjarne S. C++ programming language, 3rd Sp. Ed. 6.2 (p.120))

    You can think of it as:
    if ((UINT)iOffset < 3):

    1. tmp = (UINT)iOffset
    2. if(tmp < 3) ...
     
    maverik, Nov 26, 2008
    #4
  5. On 26 Nov., 17:06, "Joe Smith" <> wrote:
    > ".rhavin grobert" <> wrote in message
    >
    > news:...
    >
    > > typedef unsigned int UINT;

    >
    > > foo(-1);

    >
    > > void foo(int iOffset)
    > > {
    > > if ((UINT)iOffset < 3)
    > > return;
    > > // why do i get here?
    > > }

    >
    > > on my vc6 i can read in debugger that iOffset is (as expected)
    > > 0xffffffff. shouldnt ((UINT)iOffset < 3) convert to (1<3) and
    > > therefore the 'return' be called?

    >
    > Why do you expect -1 to become 1 on a cast to unsigned. I would expect it to
    > become
    > 4294967295 considering that you are clearly on a platform that uses 2's
    > complement integers, which is emphatically not less than 3. Perhaps you are
    > looking for something more like std::abs?


    Ok i thought (UINT) is a little bit more intelligent than
    reinterpret_cast<UINT>, but, thinking on it, why should it be...
     
    .rhavin grobert, Nov 26, 2008
    #5
  6. ..rhavin grobert wrote:
    >> Why do you expect -1 to become 1 on a cast to unsigned. I would expect it to
    >> become
    >> 4294967295 considering that you are clearly on a platform that uses 2's
    >> complement integers, which is emphatically not less than 3. Perhaps you are
    >> looking for something more like std::abs?

    >
    > Ok i thought (UINT) is a little bit more intelligent than
    > reinterpret_cast<UINT>, but, thinking on it, why should it be...


    Probably not enough thinking? C-style cast to 'unsigned int' is not a
    'reinterpret_cast<unsigned int>' (ignoring for a moment that there's no
    such thing as 'reinterpret_cast' between integral types in C++).
    Conversion of a signed value to 'unsigned int' evaluates to the original
    value modulo 2^N, where N is the number of value bits in 'unsigned int'.
    Which is exactly what you observe in your case.

    --
    Best regards,
    Andrey Tarasevich
     
    Andrey Tarasevich, Nov 26, 2008
    #6
  7. Andrey Tarasevich wrote:
    > Probably not enough thinking? C-style cast to 'unsigned int' is not a
    > 'reinterpret_cast<unsigned int>' (ignoring for a moment that there's no
    > such thing as 'reinterpret_cast' between integral types in C++).
    > Conversion of a signed value to 'unsigned int' evaluates to the original
    > value modulo 2^N, where N is the number of value bits in 'unsigned int'.
    > Which is exactly what you observe in your case.


    Another way of thinking about it:

    Since sizeof(int) and sizeof(unsigned int) is the same, then:

    int i = -1;
    unsigned ui = unsigned(i);
    int i2 = int(ui);

    After this i should be the same as i2 because only casts between
    integral types of the same size have been performed.

    Sometimes casting can be a bit surprising. For instance:

    signed char c = -1;
    unsigned ui = unsigned(c);

    What is the value of ui?
     
    Juha Nieminen, Nov 27, 2008
    #7
  8. .rhavin grobert

    Kai-Uwe Bux Guest

    Juha Nieminen wrote:

    > Andrey Tarasevich wrote:
    >> Probably not enough thinking? C-style cast to 'unsigned int' is not a
    >> 'reinterpret_cast<unsigned int>' (ignoring for a moment that there's no
    >> such thing as 'reinterpret_cast' between integral types in C++).
    >> Conversion of a signed value to 'unsigned int' evaluates to the original
    >> value modulo 2^N, where N is the number of value bits in 'unsigned int'.
    >> Which is exactly what you observe in your case.

    >
    > Another way of thinking about it:
    >
    > Since sizeof(int) and sizeof(unsigned int) is the same, then:
    >
    > int i = -1;
    > unsigned ui = unsigned(i);
    > int i2 = int(ui);
    >
    > After this i should be the same as i2 because only casts between
    > integral types of the same size have been performed.


    The "should" here does not refer to what is written in the standard but to
    what one might want or expect there, right? What is written [4.7/3] is that
    in this case the conversion is implementation-defined.


    Best

    Kai-Uwe Bux
     
    Kai-Uwe Bux, Nov 27, 2008
    #8
  9. .rhavin grobert

    James Kanze Guest

    On Nov 27, 11:34 pm, Juha Nieminen <> wrote:
    > Andrey Tarasevich wrote:
    > > Probably not enough thinking? C-style cast to 'unsigned int'
    > > is not a 'reinterpret_cast<unsigned int>' (ignoring for a
    > > moment that there's no such thing as 'reinterpret_cast'
    > > between integral types in C++). Conversion of a signed
    > > value to 'unsigned int' evaluates to the original value
    > > modulo 2^N, where N is the number of value bits in 'unsigned
    > > int'. Which is exactly what you observe in your case.


    > Another way of thinking about it:


    > Since sizeof(int) and sizeof(unsigned int) is the same,
    > then:


    > int i = -1;
    > unsigned ui = unsigned(i);
    > int i2 = int(ui);


    > After this i should be the same as i2 because only casts
    > between integral types of the same size have been performed.


    That's certainly not guaranteed, and typically will only be the
    case on a 2's complement machine (and even then supposing that
    the conversion to signed does no error checking). According to
    the standard, the results of converting to a signed integral
    type are implementation defined if the value being converted
    cannot be represented in the target type. The C standard is
    more explicit, and makes it clear that the implementation
    defined "result" can include generating an implementation
    defined signal.

    > Sometimes casting can be a bit surprising. For instance:


    > signed char c = -1;
    > unsigned ui = unsigned(c);


    > What is the value of ui?


    UINT_MAX, of course. Conversion to unsigned integral types is
    defined by the standard.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
     
    James Kanze, Nov 28, 2008
    #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. Bruce
    Replies:
    1
    Views:
    352
    Lucas Tam
    Aug 18, 2005
  2. falcon
    Replies:
    10
    Views:
    19,257
    Roedy Green
    Feb 24, 2006
  3. RicercatoreSbadato

    an information 'bout |

    RicercatoreSbadato, Sep 8, 2005, in forum: C++
    Replies:
    4
    Views:
    324
    red floyd
    Sep 8, 2005
  4. Tamer Ibrahim

    :( I asked a lot a bout date validation :(

    Tamer Ibrahim, Nov 12, 2007, in forum: ASP .Net
    Replies:
    1
    Views:
    316
    Paulo
    Nov 12, 2007
  5. pozz
    Replies:
    12
    Views:
    796
    Tim Rentsch
    Mar 20, 2011
Loading...

Share This Page