Array pointer aliasing - undefined behavior?
Does the following code invoke undefined behavior (due to aliasing violation or otherwise)?
int foo(int (*a)[10], int (*b)[5])
{
(*a)[5]++;
return (*b)[0];
}
int x[10];
foo(&x, 开发者_JAVA百科(int (*)[5])&x[5]);
Note that the corresponding code using plain int *
rather than pointer-to-array types would be perfectly legal, because a
and b
would be pointers to the same type and thus allowed to alias one another.
Edit: The interesting consequence, if this is in fact an aliasing violation, is that it seems to be a hackish but valid way to get restrict
semantics pre-C99. As in:
void some_func(int *aa, int *bb)
{
int (*a)[1] = (void *)aa;
int (*b)[2] = (void *)bb;
/* Now **a and **b can be assumed by the compiler not to alias */
}
Presumably if you needed to access an actual array at each address, you could use SIZE_MAX-1 and SIZE_MAX-2 etc. as the differing sizes.
You are not accessing objects through pointers of different type here: you are not manipulating the array objects to which a
and b
point themselves but the objects pointed to by (*a)+5
and (*b)+0
, namely *((*a)+5)
and *((*b)+0)
. Since these are pointers to the same type they may well alias to the same object.
The implicit assignment by the ++
operator is a valid assignment to the object pointed to by (*b)+0
: ++
is equivalent to x = x + 1
(besides x
being evaluated only once) and for simple assignment =
the standard says
If the value being stored in an object is read from another object that overlaps in any way the storage of the first object, then the overlap shall be exact and the two objects shall have qualified or unqualified versions of a compatible type; otherwise, the behavior is undefined.
The types here are exactly the same and the overlap is exact.
精彩评论