您有时可以使用限制限定的指针来访问与其他指针相同的对象,但前提是未修改指向的对象。这是 C 2011 (N1570) 6.7.3.1 第 1-3 段和第 4 段的第一部分,其中穿插了它们如何应用于问题中的代码。
6.7.3.1 限制的正式定义
1 令D是一个普通标识符的声明,它提供了一种将对象P指定为类型T的限制限定指针的方法。
这样int * restrict a
的声明D也是如此。当max
用 调用时max(&num, &num);
,对象P是num
(或更正式地,由 命名的对象num
),而T是int
。同样,int * restrict b
是另一个这样的声明。
2 如果D出现在一个块内并且没有存储类 extern,则让B表示该块。如果D出现在函数定义的参数声明列表中,则让B表示关联的块。否则,让B表示main块(或在独立环境中程序启动时调用的任何函数块)。
这些声明出现在函数定义的参数声明中,所以B是函数定义的块,即max
.
3 在下文中,指针表达式E被称为基于对象P如果(在执行B的某个序列点处,在评估E之前)修改P以指向它之前所在的数组对象的副本指向会改变 E.137 的值)请注意,“基于”仅针对具有指针类型的表达式定义。
该函数max
包含指针表达式a
和b
,每个两次,因此它们都是指针表达式E的实例。这些表达式分别取决于参数a
和b
,因为如果我们更改a
为指向 的副本num
而不是指向num
,那么a
(显然)将具有不同的值,对于b
. (虽然num
是一个标量对象,但它就像一个包含单个元素的数组,用于指针运算。)
4 在每次执行B期间,令L为基于P具有&L的任何左值。如果L用于访问它指定的对象X的值,并且X也被修改(通过任何方式),则适用以下要求:...</p>
在 的执行过程中max
,左值*a
的地址 ( &*a
,即a
) 基于P ( a
),因此左值*a
是L的一个实例。此左值用于访问num
,num
对象X的实例也是如此。但是num
在执行过程中永远不会被修改max
。因此,以下要求不适用。类似地,左值*b
指的num
是在执行期间从未修改过的对象 () max
。
因此, 中的代码max
不违反 的要求restrict
,其行为由 C 标准定义。