Reputation: 22318
If I have a pointer (unsigned long *uptr)
to an array of (unsigned long)
- or any type with (typically) stricter alignment requirements than (char)
- and cast:
char *bptr = (char *) uptr; /* always works. */
Does casting (bptr)
to (unsigned long *)
yield the original pointer? I realise that casting to a pointer with stricter alignment requirements may not yield a pointer that can be safely derefenced, in general. But does the standard guarantee the round-trip of the pointer value in this case?
I can't imagine an implementation of (char *)
where this wouldn't work as expected, given that it must have at least as many bits in its representation to address bytes. Other answers make the general case clear. It just never occurred to me to question whether this was guaranteed.
Upvotes: 2
Views: 321
Reputation: 10868
Yes.
Quoting the same block of text as Kerrek, since the char* pointer must be correctly aligned for the referenced type
undefined behaviour is avoided and the result shall compare equal
.
If it was any type other than char, or if you change the value of the char* pointer, then the pointer may no longer be correctly aligned
and you're back into UB.
You're treading a narrow line, but it's perfectly safe to go there.
Upvotes: 1
Reputation: 477010
It looks like you're fine. C11 6.3.2.3/7 says:
A pointer to an object type may be converted to a pointer to a different object type. If the resulting pointer is not correctly aligned for the referenced type, the behavior is undefined. Otherwise, when converted back again, the result shall compare equal to the original pointer. When a pointer to an object is converted to a pointer to a character type, the result points to the lowest addressed byte of the object. Successive increments of the result, up to the size of the object, yield pointers to the remaining bytes of the object.
Upvotes: 2