bobbay - 1 year ago 81
C Question

# Why cast to a pointer then dereference?

I was going through this example which has a function outputting a hex bit pattern to represent an arbitrary float.

``````void ExamineFloat(float fValue)
{
printf("%08lx\n", *(unsigned long *)&fValue);
}
``````

Why take the address of fValue, cast to unsigned long pointer, then dereference? Isn't all that work just equivalent to a direct cast to unsigned long?

``````printf("%08lx\n", (unsigned long)fValue);
``````

I tried it and the answer isn't the same, so confused.

``````(unsigned long)fValue
``````

This converts the `float` value to an `unsigned long` value, according to the "usual arithmetic conversions".

``````*(unsigned long *)&fValue
``````

The intention here is to take the address at which `fValue` is stored, pretend that there is not a `float` but an `unsigned long` at this address, and to then read that `unsigned long`. The purpose is to examine the bit pattern which is used to store the `float` in memory.

As shown, this causes undefined behavior though.

Reason: You may not access an object through a pointer to a type that is not "compatible" to the object's type. "Compatible" types are for example (`unsigned`) `char` and every other type, or structures that share the same initial members (speaking of C here). See ยง6.5/7 N1570 for the detailed (C11) list (Note that my use of "compatible" is different - more broad - than in the referenced text.)

Solution: Cast to `unsigned char *`, access the individual bytes of the object and assemble an `unsigned long` out of them:

``````unsigned long pattern = 0;
unsigned char * access = (unsigned char *)&fValue;
for (size_t i = 0; i < sizeof(float); ++i) {
pattern |= *access;
pattern <<= CHAR_BIT;
++access;
}
``````

Note that (as @CodesInChaos pointed out) the above treats the floating point value as being stored with its most significant byte first ("big endian"). If your system uses a different byte order for floating point values you'd need to adjust to that (or rearrange the bytes of above `unsigned long`, whatever's more practical to you).

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download