给定一个基于另一个的限制指针,它们应该永不别名吗?

据我了解section 6.7.3.1 of the C standard中“限制”的正式定义, 在下面的函数中,指针y基于restrict指针x;因此,编译器将假定访问*x*y可能是别名:

void assign1(int *pA,long N) {
  int *restrict x = pA;
  { 
    int *y = x + N;
    *x = *y;
  }
}

但是,如果将y本身声明为restrict怎么办:编译器可以假设*x*y永远不会混叠吗?

void assign2(int *pA,long N) {
  int *restrict x = pA;
  { 
    int *restrict y = x + N;
    *x = *y;
  }     
}
xxingx 回答:给定一个基于另一个的限制指针,它们应该永不别名吗?

Quoting Jeroen Dobbelaere,致力于“限制”实现的LLVM开发人员:

这是在6.7.3.1 paragraph 4中定义的:

...用于访问X值的所有其他左值也应基于P ...

对于assign1

  • x是一个限制指针,并假定指向自己的对象集
  • y是基于x
  • 的普通指针
  • 对所有x所指向的对象的访问都是通过基于x的指针完成的。

assign2

  • x是一个限制指针,并假定指向自己的对象集
  • y还是基于x的限制指针,但是在y的范围内假定它指向自己的对象集。
  • 因此,*x*y绝不能重叠,因为对y对象的所有访问都必须基于从y派生的指针进行

这样,N = 0将触发assign2中的未定义行为

对内部块外部的*x进行赋值,使代码再次有效:

void assign3(int *pA,long N) {
  int *restrict x = pA;
  int tmp;
  {
    int *restrict y = x + N;
    tmp = *y;
  }
  *x = tmp; // may alias with *y
}
本文链接:https://www.f2er.com/2777106.html

大家都在问