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.