For Programmers: Free Programming Magazines  


Home > Archive > VC Language > May 2006 > unsigned __int64 typecast bug?









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author unsigned __int64 typecast bug?

2006-05-27, 7:05 pm

This does not seem like correct behavior.
Running on Windows XP SP2 32bit
Have tested this with VS 2003 C complier and WS2003 SP1 DDK.

The code below will generate the following results:
good= f1111000, nosign= 4fffffff, badsign= fffffffff1111000, uito64=
f1111000

The typecast of a 32 bit pointer to (unsigned __int64) is causeing sign
extension. The typecast does the correct thing for an unsigned int, but not
pointers.

Why would one do this? Well I had an unsigned _int64 array of debug info I
was passing from driver to app and thought hey I could throw a few buffer
addresses in there and it would be easy to dump them with the rest of the
data.
It works correctly if I typecast to (unsigned int), but that seems like an
odd way of doing this.
Cliff

int _tmain(int argc, _TCHAR* argv[])

{

unsigned __int64 good, badsign, nosign, uito64;

unsigned int *ptr, *ptr2;

unsigned int ui;

ptr = (unsigned int *)0xf1111000; // 32bit addr high bit set

ptr2 = (unsigned int *)0x4fffffff; // 32bit addr high bit not set

badsign = (unsigned __int64) ptr;

nosign = (unsigned __int64) ptr2;

good = (unsigned int) ptr;

ui = 0xf1111000;

uito64 = (unsigned __int64) ui;



printf("good= %I64x, nosign= %I64x, badsign= %I64x, uito64= %I64x\n", good,
nosign, badsign,uito64);

return 0;

}


Doug Harrison [MVP]

2006-05-27, 7:05 pm

On Sat, 27 May 2006 12:12:42 -0700, <test> wrote:

>This does not seem like correct behavior.
>Running on Windows XP SP2 32bit
>Have tested this with VS 2003 C complier and WS2003 SP1 DDK.
>
>The code below will generate the following results:
>good= f1111000, nosign= 4fffffff, badsign= fffffffff1111000, uito64=
>f1111000
>
>The typecast of a 32 bit pointer to (unsigned __int64) is causeing sign
>extension. The typecast does the correct thing for an unsigned int, but not
>pointers.
>
>Why would one do this? Well I had an unsigned _int64 array of debug info I
>was passing from driver to app and thought hey I could throw a few buffer
>addresses in there and it would be easy to dump them with the rest of the
>data.
>It works correctly if I typecast to (unsigned int), but that seems like an
>odd way of doing this.
>Cliff
>
>int _tmain(int argc, _TCHAR* argv[])
>
>{
>
>unsigned __int64 good, badsign, nosign, uito64;
>
>unsigned int *ptr, *ptr2;
>
>unsigned int ui;
>
>ptr = (unsigned int *)0xf1111000; // 32bit addr high bit set
>
>ptr2 = (unsigned int *)0x4fffffff; // 32bit addr high bit not set
>
>badsign = (unsigned __int64) ptr;
>
>nosign = (unsigned __int64) ptr2;
>
>good = (unsigned int) ptr;
>
>ui = 0xf1111000;
>
>uito64 = (unsigned __int64) ui;


This last cast is unnecessary.

>printf("good= %I64x, nosign= %I64x, badsign= %I64x, uito64= %I64x\n", good,
>nosign, badsign,uito64);
>
>return 0;
>
>}


I don't know if the conversion sequence from 32 bit pointer to 64 bit
unsigned integer is documented, but the conversion from 32 bit pointer to
64 bit pointer does sign extend in Win64:

http://msdn.microsoft.com/library/d...ng_pointers.asp
<q>
Be careful when using POINTER_32 values in code that may be compiled as
64-bit code. The compiler will sign-extend the pointer when it is assigned
to a native pointer in 64-bit code, not zero-extend the pointer.
</q>

If I were to guess, the compiler is widening the pointer to 64 bits and
then performing the cast, or maybe it's converting to a 32 bit int first,
but from a language standard point of view, all this is at best
implementation-defined and may be unspecified. Really all you can portably
do is cast back to the original type, which should produce the original
value. The intermediate values needn't be what you might expect, but it
looks like you've found a way to get what you want.

--
Doug Harrison
Visual C++ MVP
Sean M. DonCarlos

2006-05-27, 7:05 pm

"test" wrote:

> This does not seem like correct behavior.
> Running on Windows XP SP2 32bit
> Have tested this with VS 2003 C complier and WS2003 SP1 DDK.
>
> The code below will generate the following results:
> good= f1111000, nosign= 4fffffff, badsign= fffffffff1111000, uito64=
> f1111000
>
> The typecast of a 32 bit pointer to (unsigned __int64) is causeing sign
> extension. The typecast does the correct thing for an unsigned int, but not
> pointers.
>
> Why would one do this? Well I had an unsigned _int64 array of debug info I
> was passing from driver to app and thought hey I could throw a few buffer
> addresses in there and it would be easy to dump them with the rest of the
> data.
> It works correctly if I typecast to (unsigned int), but that seems like an
> odd way of doing this.
> Cliff
>
> int _tmain(int argc, _TCHAR* argv[])
>
> {
>
> unsigned __int64 good, badsign, nosign, uito64;
>
> unsigned int *ptr, *ptr2;


These are pointers to unsigned ints. The address are not necessarily
unsigned ints!

> unsigned int ui;
>
> ptr = (unsigned int *)0xf1111000; // 32bit addr high bit set
>
> ptr2 = (unsigned int *)0x4fffffff; // 32bit addr high bit not set
>
> badsign = (unsigned __int64) ptr;


Windows has the option of interpreting this as: Take ptr and interpret it as
a signed int. Cast this int to __int64 by sign-extending it, and then make it
unsigned. At least, 64-bit Windows is documented to do this.

> nosign = (unsigned __int64) ptr2;
>
> good = (unsigned int) ptr;
>
> ui = 0xf1111000;
>
> uito64 = (unsigned __int64) ui;
>
>
>
> printf("good= %I64x, nosign= %I64x, badsign= %I64x, uito64= %I64x\n", good,
> nosign, badsign,uito64);
>
> return 0;
>
> }


I would first ensure that ptr is unsigned before casting it to a 64-bit type:

unsigned int * ptr = (unsigned int *)(0xf1110000);
unsigned __int64 uiTest = (UINT_PTR)ptr;
printf("uiTest = %I64x", uiTest);

Should produce as output: uiTest = f1110000

Sean
Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com