On Sat, 19 Jul 2003, Shachar Shemesh wrote:
: >Use intptr_t. If that's not available (via autoconf test), typedef intptr_t : >to be "unsigned long" locally, as "long" is the size of a pointer on all : >typical ILP32 and LP64 hosts.
: The reason something is a warning and not an error is that it MAY have a : legitimate use. As such, there should always be a way to change the code : so that it will keep the same meaning, but will avoid the warning in the : future.
Yes. "Use intptr_t", just like I've already said.
: In this particular case, for example, what does applying the : following change do? : - if (!((int)id >> 16)) return wine_dbg_sprintf( "<guid-0x%04x>", : (int)id & 0xffff ); : + if (!((int)id >> 16)) return wine_dbg_sprintf( "<guid-0x%04x>", : (UINT16)id ); : : I'm a bit confused. gcc seems to be warning us about an explicit cast?
Yes, because explicitly casting a pointer to an integer of a smaller size is unportable (it's even warned against in the current C standards), and can cause crashes. The most common usage is void* -> int -> void*, which used to be in huge swaths of C code before it was pruned out for LP64 usage.
To do this correctly per the C standard, cast to an integer of at least the pointer's size (intptr_t), and then cast it further down:
For the first case,
((intptr_t)id >> 16)
For the second one,
(UINT16)(intptr_t)id