Consider the following C code:
int arr[2] = {0, 0};
int *ptr = (int*)&arr;
ptr[0] = 5;
printf(\"%d\\n\", arr[0]);
Now, it is clear that
Here is a slightly refactored version of your code for easier reference:
int arr[2] = { 0, 0 };
int *p1 = &arr[0];
int *p2 = (int *)&arr;
with the question being: Is p1 == p2
true, or unspecified, or UB?
Firstly: I think that it is intended by the authors of C's abstract memory model that p1 == p2
is true; and if the Standard doesn't actually spell it out then it would be a defect in the Standard.
Moving on; the only relevant piece of text seems to be C11 6.3.2.3/7 (irrelevant text excised):
A pointer to an object type may be converted to a pointer to a different object type. [...] 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.
It doesn't specifically say what the result of the first conversion is. Ideally it should say ...and the pointer points to the same address, but it doesn't.
However, I argue that it it is implied that the pointer must point to the same address after the conversion. Here is an illustrative example:
void *v1 = malloc( sizeof(int) );
int *i1 = (int *)v1;
If we do not accept "and the pointer points to the same address" then i1
might not actually point into the malloc
'd space, which would be ridiculous.
My conclusion is that we should read 6.3.2.3/7 as saying that the pointer cast does not change the address being pointed to. The part about using pointers to character type seems to back this up.
Therefore, since p1
and p2
have the same type and point to the same address, they compare equal.