关于C#:别名” conststrict”指针参数是否合法?

Is it legal to alias “const restrict” pointer arguments?

如果dot_product被声明为

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

将用

对其进行调用

1
dot_product(x, x, x_len)

根据C99标准是否为"未定义"?

编辑

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


我没有原始的C99(即ISO9899:1999)文本;我只有ISO9899:2007:TC3的副本。我希望该文本取自该文档的第111页,与C99标准中的文本非常相似。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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.

这似乎可以清楚地调用您所要求的具有定义行为的形式的函数,前提是别名指针用于只读访问。通过任何一个别名指针进行写入都会调用未定义的行为。


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

然后,如果指向对象"以任何方式"被修改,则与restrict相关的UB只能出现。因此,只要不修改向量,一切都很好。由于const限定,在函数内部不应发生这种情况。而且,如果外面的某些东西(例如不同的线程或信号处理程序)修改了向量,则无论如何您都被搞砸了。


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

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

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

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

由于您的函数调用为

1
dot_product(x, x, x_len)

将相同的指针x传递给该函数的

,更新ab中的任何一个都会影响其他导致不确定行为的行为。