c - 这个具体示例是否是 C99 中 restrict 关键字的未定义行为?

标签 c gcc

我查看了所有答案,但我无法得到关于以下示例是否为未定义行为的答案。 它与 C99 规范的 6.7.3.1 中的示例相同。

示例 3 函数参数声明

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];
}

说明如何通过两个受限指针为未修改的对象取别名。特别是,如果 a 和 b 是不相交的数组,则 h(100, a, b, b) 形式的调用具有定义的行为,因为数组 b 未在函数 h 内修改。

简而言之,如果 b 未在函数 h 中修改,则明确提到它是已定义的行为。但是,如果以 h(100, a, a, b) 的形式调用是否是未定义行为?

多一点背景,为什么我想说清楚。我们希望以就地或不就地方式使用一些基本功能。为了减少工作量,我们希望不需要同时提供h(int n, int * restrict p, int * restrict q, int * restrict r) h_inplace(int n, int * restrict p, int * restrict q).从目前的观察来看,gcc、clang、icc、msvc 似乎可以给出正确的结果,即使我们以 h(100, a, a, b) 的形式调用它。但是,如果它是未定义的行为(这意味着它可能来自其他编译器或 gcc、clang、icc、msvc 的 future 版本),我们绝对不希望有风险。你怎么看?

最佳答案

h(100, a, a, b) 显然会导致 UB,因为 pq promise 不会相互混淆,并且代码通过其中一个写入。参见 C11 6.7.3.1/4:

If L is used to access the value of the object X that it designates, and X is also modified (by any means), then the following requirements apply: [...] Every other lvalue used to access the value of X shall also have its address based on P

通过p 写入访问一个对象(这里称为X)的值,并修改它。因此,函数中用于访问对象的每个左值都必须从 p 生成。但是 q 不是从 p 生成的。

关于c - 这个具体示例是否是 C99 中 restrict 关键字的未定义行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34347856/

相关文章:

c - 将变量从 .bss 移动到 .data 是否危险?

c - 传递要在 C 函数中修改的动态分配矩阵

模拟默认定义的条件宏定义

c - 从二进制文件中读取 4 字节日期(大端)

c - 在 C 中的变量中定义的数组大小无法在 IAR 中编译,但在 Keil 中构建良好

c++ - 在构建我的 C++ 可执行文件 (gcc) 时,我可以获得所有链接库的报告吗? (包括静态链接)

c - 删除硬盘时 "Verifies the write"是什么意思?

任何人都可以破译为什么这个 'find unique values' 进程不能按预期工作吗?

c - 请解释一下C程序的这个功能是如何工作的?

无法使用 "gcc"进行编译