我查看了所有答案,但我无法得到关于以下示例是否为未定义行为的答案。 它与 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,因为 p
和 q
promise 不会相互混淆,并且代码通过其中一个写入。参见 C11 6.7.3.1/4:
If
L
is used to access the value of the objectX
that it designates, andX
is also modified (by any means), then the following requirements apply: [...] Every other lvalue used to access the value ofX
shall also have its address based onP
通过p
写入访问一个对象(这里称为X
)的值,并修改它。因此,函数中用于访问对象的每个左值都必须从 p
生成。但是 q
不是从 p
生成的。
关于c - 这个具体示例是否是 C99 中 restrict 关键字的未定义行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34347856/