William S Fulton <ws*@fultondesigns.co.ukwrites:
Keith Thompson wrote:
>William S Fulton <ws*@fultondesigns.co.ukwrites:
>>I'm looking for the name of the following casting style in order to do
some reading around on it and why it is sometimes used.
unsigned long long ull = 0;
void * ptr = 0;
ull = *(unsigned long long*)&ptr;
As opposed to the more usual casting:
ull = (unsigned long long)ptr;
I think it is just to silence compiler warnings, but if anyone has links
with further information, that would be great.
Are you sure that's the actual code? It's treating an object of type
void* as if it were an object of type unsigned long long. There's no
reason to assume that they're going to be the same size.
Please don't send me e-mail copies of Usenet followups.
[...]
Still, that is a bit of digression and I am really looking to find out
if this type of casting has a name. I think I read a long time ago, it
was some sort of universal type of cast that would never fail to compile
on all systems, or something like.
It's a form of type punning, i.e., pretending that an object (memory
region) holding something of one type holds a value of a different
type.
The difference between
ull = *(unsigned long long*)&ptr;
and
ull = (unsigned long long)ptr;
is that the first pretends that the object ptr holds a value of type
unsigned long long, whereas the second *converts* the value of ptr
(which is of type void*) to unsigned long long. A conversion from a
pointer type to an integer type is implementation-defined; it may just
reinterpret the same bit pattern, or it may perform some non-trivial
conversion (as conversions between integers and floats do). On *most*
systems, conversion between a pointer and an integer *of the same
size* just copies the bits.
Note that if, for example, void* is 32 bits and unsigned long long is
64 bits, the statement
ull = *(unsigned long long*)&ptr;
attempts to read 64 bits from a 32-bit object. This invokes undefined
behavior; most likely, ull will contain 32 bits from the pointer
object and another 32 bits of whatever garbage happened to be stored
next to it. And these could be in either order. On the other hand,
converting from void* to unsigned long long, though it's
implementation-defined doesn't attempt to read garbage. Most likely
(if sizeof(unsigned long long) sizeof(void*)) it will just copy the
bits of the pointer and zero-extend the result.
--
Keith Thompson (The_Other_Keith)
ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.