question 'bout less-than and cast to unsigned

R

.rhavin grobert

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?
 
T

Thomas J. Gritzan

..rhavin grobert said:
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.
 
J

Joe Smith

.rhavin grobert said:
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?
 
M

maverik

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) ...
 
R

.rhavin grobert

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...
 
A

Andrey Tarasevich

..rhavin grobert said:
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.
 
J

Juha Nieminen

Andrey said:
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?
 
K

Kai-Uwe Bux

Juha said:
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
 
J

James Kanze

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.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top