【问题标题】:How to tell a C or a C++ compiler that pointers are not aliased如何告诉 C 或 C++ 编译器指针没有别名
【发布时间】:2011-09-07 03:08:07
【问题描述】:

我有一个函数可以接收这样的指针数组:

void foo(int *ptrs[], int num, int size)
{ 
  /* The body is an example only  */
     for (int i = 0; i < size; ++i) { 
       for (int j = 0; j < num-1; ++j)
         ptrs[num-1][i] += ptrs[j][i];
     }
}

我想传达给编译器的是指针ptrs[i] 不是彼此的别名,并且数组ptrs[i] 不重叠。我该怎么做?我别有用心是鼓励自动矢量化。

另外,有没有办法在 std::vector 的迭代器上获得与 __restrict__ 相同的效果?

【问题讨论】:

  • 重要提示:C++ 标准不支持 C99 中的 restrict 限定符——它甚至不是关键字。因此,在 C++ 程序中对 restrict 的任何使用都依赖于实现扩展

标签: c++ c pointers pointer-aliasing restrict-qualifier


【解决方案1】:

restrict 与更常见的const 不同,它是指针 的属性,而不是指向的数据。因此它属于“*”声明修饰符的右侧。参数声明中的[] 是编写* 的另一种方式。把这些东西放在一起,用这个函数原型应该可以得到你想要的效果:

void foo(int *restrict *restrict ptrs, int num, int size)
{
   /* body */
}

并且不需要新名称。 (未经测试。您的里程可能会有所不同。restrict 是一个纯粹的优化提示,实际上可能不会对您的编译器做任何建设性的事情。)

【讨论】:

  • 除非我弄错了,否则其中一个“限制”声明是多余的;没有其他可能发生别名的“int **”类型变量。 “int *restrict * ptrs”应该可以完成这项工作。我想知道“int * restrict ptrs[]”是否也可以这样做......
  • 恕我直言,restricts 都是必需的,因为其他指针可能存在于 foo 范围之外。
  • "我想传达给编译器的是指针...不是彼此的别名"
  • 另外,迟到的评论,但指针的语义“在foo 的范围之外”不受 foo 参数上的restrict 限定符的影响。第二个restrict 不是必需的。
【解决方案2】:

类似:

void foo(int *ptrs[], int num, int size)
{ 
  /* The body is an example only  */
     for (int i = 0; i < size; ++i) { 
       for (int j = 0; j < num-1; ++j) {
         int * restrict a = ptrs[num-1];
         int * restrict b = ptrs[j];
         a[i] += b[i];
     }
}

...我认为应该在 C99 中执行此操作。我不认为C++有什么办法,但是很多C++编译器也支持restrict。

【讨论】:

  • 啊,我知道了,我得介绍新名字了。谢谢。
  • 顺便说一句,您可以使用类似的技巧将迭代器的对象引用标记为无别名(即将其地址分配给受限指针)。
  • 您在此处的“*”的错误一侧使用了“restrict”限定符。
  • @davmac 你的意思是像__restrict__ ptr = &amp; (*iter) 这样的东西吗?好像能用,不错谢谢。
【解决方案3】:

在 C++ 中,如果指针参数指向根本不同的类型(“严格别名”规则),则假定指针参数不具有别名。

在 C99 中,“restrict”关键字指定指针参数不为任何其他指针参数设置别名。

【讨论】:

  • 非常肯定严格的别名规则适用于cc++stackoverflow.com/questions/98650/…
  • 是的,是的。此外,这个答案不会告诉 OP 他或她不知道的任何事情。
  • 严格的别名规则在C++中效率更高,因为参数往往是std::vector&lt;int&gt;&amp;而不是int*
猜你喜欢
  • 1970-01-01
  • 2020-10-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-14
  • 1970-01-01
  • 1970-01-01
  • 2010-12-12
相关资源
最近更新 更多