请考虑以下代码:
extern int A[2];
/* Just returns `p` back. */
extern int *identity(int *p);
int f(int *restrict p)
{
int *q = identity(p); /* `q` becomes "based on" `p` */
int *r = A + (p == q);
*p = 1;
*r = 2;
return *p;
}
r
是以p
为基础的吗?根据标准,似乎是必须的.尤其是:
[...]如果(在E求值之前执行B的某个顺序点)修改P以指向它以前指向的数组对象的副本将改变E的值,则指针表达式E被称为基于对象P.
其中P
是:
指向类型T的限制限定指针.
根据上述定义,r
is基于p
,因为"修改p
将改变A + (p == q)
的值"(因此r
‘S).Even though r
肯定会指向A
数组内部,它仍然必须以p
为基础,这是违反直觉的.也许这就是我错的地方.
GCC和Clang do not认为上述情况属实.他们将p
上的最后一次加载优化为return 1;
.因此,f(&A[1])
会错误地返回1
,而不是2
.
执行者是否误解了标准?如果不是,那么f(&A[1])
是未定义的行为,但是why,我错过了什么?
谢谢!