别名“const restrict”指针参数是否合法?

时间:2013-12-18 09:16:03

标签: c pointers c99 aliasing restrict-qualifier

如果dot_product被声明为

float dot_product(const float* restrict a, const float* restrict b, unsigned n);

会用

来调用它
dot_product(x, x, x_len)
根据C99标准,

是“未定义的”?

修改

x是一个指针,当然指向sizeof(float) * x_len个字节的内存,x_lenunsigned。这个问题是关于别名的。

3 个答案:

答案 0 :(得分:6)

我没有原始的C99(即ISO9899:1999)文字;我只有ISO9899:2007:TC3的副本。我希望从该文件第111页开始的这篇文章与C99标准中的文字非常相似。

6.7.3.1 Formal definition of restrict

...

10. EXAMPLE 3

The function parameter declarations

    void h(int n, int * restrict p, int * restrict q, int * restrict r)
    {
        int i;
        for (i = 0; i < n; i++)
            p[i] = q[i] + r[i];
    }

illustrate how an unmodified object can be aliased through two restricted
pointers. In particular, if a and b are disjoint arrays, a call of the form
h(100, a, b, b) has defined behavior, because array b is not modified within
function h.

如果使用别名指针进行只读访问,这似乎可以清楚地调出您所询问的具有已定义行为的表单的函数。通过任何一个别名指针写入都会调用未定义的行为。

答案 1 :(得分:1)

首先,我不认为调用本身是UB,如果作为参数传递的指针以与restrict规范冲突的方式使用,则UB只能在函数内部发生。 (UB对调用没有多大意义,如果那个(w / sh)被禁止,这应该是违反约束而不是UB。)

然后,如果指向的对象被“以任何方式”修改,则只能出现与restrict相关的UB。所以只要你的矢量没有修改,一切都很好。在你的函数内部,由于const限定,这不应该发生。如果外面的某些东西(例如一个不同的线程或一个信号处理程序)修改了你的向量,你就会被搞砸了。无论如何。

答案 2 :(得分:-1)

是。它将调用未定义的行为。

如果使用restrict关键字并且该函数声明为:

float dot_product(const float* restrict a, const float* restrict b, unsigned n);

然后允许编译器假设ab指向不同的位置,更新一个指针不会影响其他指针。程序员而不是编译器负责确保指针不指向相同的位置

由于你的函数调用是

dot_product(x, x, x_len)  

将相同的指针x传递给函数,更新ab中的任何一个都会影响其他导致未定义的行为。