6

如果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。这个问题是关于别名的。

4

3 回答 3

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.

如果别名指针用于只读访问,这似乎清楚地调用了您询问的具有已定义行为的形式的函数。通过任何一个别名指针写入都会调用未定义的行为。

于 2013-12-18T09:45:18.223 回答
1

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

restrict然后,只有当指向的对象被“以任何方式”修改时,UB才会出现。所以只要你的向量没有被修改,一切都很好。在你的函数内部,这不应该发生,因为有const资格。如果外部的东西(比如不同的线程或信号处理程序)修改了你的向量,无论如何你都被搞砸了。

于 2013-12-18T09:51:38.417 回答
-1

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

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

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

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

由于您的函数调用是

dot_product(x, x, x_len)  

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

于 2013-12-18T09:17:17.493 回答