我一直在使用限制合格的指针工作了很多,我想到了一些东西,虽然我不这样做,但它似乎是标准兼容的这一事实让我怀疑我是否遗漏了一些东西。理解标准。特别是,据我所知,可以以标准兼容的方式获得指向同一数据块的两个限制限定指针。请考虑以下示例。
int* restrict p = (int[2]){0,0};
int* restrict* x = (int* restrict*)(int*[1]){p};
**x = 1;
p[1] = 2;
我将int*
分配给p
不限制,这样就不会违反与分配限制合格指针相关的标准部分,6.7.3.1第4段。是6.7.3.1的整体,供参考。
6.7.3.1限制的正式定义
1设D是普通标识符的声明,提供指定的方法 object P作为类型T的限制限定指针。
2如果D出现在一个块内并且没有存储类extern,那么让B表示 块。如果D出现在函数定义的参数声明列表中,则设B 表示相关块。否则,让B表示主块(或块) 在独立环境中的程序启动时调用的任何函数。)
3在下文中,指针表达式E被称为基于对象P if(在某些情况下) 在评估E)之前执行B的序列点将P修改为指向 它以前指向的数组对象的副本将改变E的值.137) 请注意,''based''仅针对具有指针类型的表达式定义。
4在每次执行B期间,让L为基于P的具有& L的左值。如果L用于 访问它指定的对象X的值,并且X也被修改(通过任何方式), 那么以下要求适用:T不应该是合格的。每个其他左值 用于访问X的值也应该具有基于P的地址。每次访问都是如此 为了本条款的目的,修改X也应被视为修改P.如果P. 被赋予基于另一个受限指针的指针表达式E的值 对象P2,与块B2相关联,然后B2的执行将在之前开始 B的执行或B2的执行应在分配之前结束。如果这些 如果要求不符合,则行为未定义。
5这里B的执行意味着程序的执行部分会 对应于具有标量类型和自动存储持续时间的对象的生命周期 与B相关联。
6翻译人员可以自由忽略使用限制的任何或所有别名含义。
所以,然后我将指向非限定类型的指针转换为指向该类型的限定版本的指针,在6.3.2.3第2段中允许:
对于任何限定符q,指向非q限定类型的指针可以转换为指向的指针 该类型的q限定版本;存储在原始和转换指针中的值 应比较平等。
然后我将这个转换后的指针存储到一个新对象x
。第4段似乎没有涵盖这一点,因为x
没有从基于通过普通标识符的声明D指定的对象P的表达式中分配(没有与{已分配{1}}。
现在x
是一个具有限制限定有效类型的对象,它基于p。使用两个指针修改数组的一个元素会违反只有基于*x
的表达式可以修改任何基于*x
的表达式修改的对象的情况,所以很难看出你是怎么做的可以让事情像这样失控。
尽管如此,我所处理的情况并不那么人为(这对于一个问题来说太长了),任何不允许这样做的事情都可能与我正在做的事情有关。
所以,简而言之,我的问题是: