对于restrict指针p,Based-On的定义意味着若令int* n = p,&*n并非以p 为基准

编程语言 2026-07-08

《C99标准草案n1256》在6.7.3.1p3、6.7.3.1p4中关于restrict限定指针的描述如下:

3在下文中,当且仅当一个指针表达式 E 基于对象 P 时成立,如果在对 B 的执行过程中的某个序列点,且在对 E 进行评估之前,对 P 进行修改,使其指向其原来所指向的数组对象的副本,将改变 E 的值。注意,“based” 这个词只对指针类型表达式有定义

4在每次执行 B 时,让 L 成为一个具有基于 P&L 的左值。如果 L 被用于访问它所指示的对象 X 的值,且 X 也被修改(以任何方式),则下列要求适用:T 不能有const限定。用于访问 X 的值的其他所有左值的地址也应以 P 为基址。任何修改 X 的访问在本小条的目的下也应被视为同时修改 P

出于方便起见,下面复制了一个对 another post 所示程序进行轻微修改(仅变量名改名)的版本。

int main(void){
        int x = 5;

        int* restrict p;
        p = &x;

        *p = 10;
        //*p is an lvalue where &*p is based on p
        //x is modified so semantics of 6.7.3.1p4 apply 

        int* n = p;
        *n = 20;
        //&*n is not based on p, since if p were to change prior to *n,
        //the value of &*n would not change
        //hence this access is not valid
}

我写了注释,解释为什么我认为 *n = 20; 违反了restrict qualified pointers的规则。据我理解,在 n 的声明之后就有一个序列点。*n 是用来访问由 x 指定的对象的左值。如果在这一序列点将 p 改为指向 x 的一个副本,那么 &*n 的左值的地址将不会改变。因此 &*n 并非基于 p,所以这次访问违反了restrict qualified pointers的规则。

然而,对这篇帖子的另一位发言人gnasher729的评论是这样说的:

In this case you have no undefined behaviour because n is based on p. If you wrote n = &x then n wouldn’t be based on p leading to undefined behaviour.

这与我对restrict qualified pointers的理解相矛盾,我感到困惑。请问有人能解释在上面的程序中,为什么 &*n 不是基于 p,我的推理哪里出错?

此贴并非与 另一个帖子 重复,因为该帖子并未要求澄清/纠正我对restrict指针的理解,也没有提供任何帮助来澄清/纠正我的理解。比如,它没有解释为什么 &*N 基于 P,以及我的推理为什么是错的。

解决方案

n&*n 基于 p。在初始赋值之后、在 int* n = p; 之前修改 p,将会改变 n,这属于可用的块 B

条件“在 某个 序列点…”若存在一个序列点能使剩余条件成立,则该条件成立。存在其他序列点并不满足该条件的事实并不相关;该条件并不要求在每一个序列点都成立。

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章