它是安全的代码,还是编译器可以通过
p
优化访问,使得*p
会导致42
?
#include <stdio.h>
int i = 42;
int *d = &i;
void test(int const *p)
{
*d = 43;
printf("%d, %p\n", *p, (void *) p);
printf("%d, %p\n", *d, (void *) d);
}
int main() {
test(d);
return 0;
}
我发现
*p
通常是用43
打印的,但我想知道这里是否有任何陷阱,所以在某些情况下打印*p
可能会产生42
。
这里的一个关键误解可能是如何将参数传递给 C 中的函数。它们是按值传递的。
当
d
传递给test
时,指针的值(内存地址)被复制到const指针p
中。两者都包含相同的内存地址,但只有 p
受到 const
的约束。
如果您尝试通过修改
p
来更新该地址处的数据,您将遇到错误,但 d
没有类似的约束,因此它可以用于更新该内存地址处的数据。
两个指针仍然指向相同的数据,因此打印
p
指向的 int 显示 43
。
它是安全的代码吗?还是编译器可以通过 p 优化访问,使得 *p 的结果为 42?
安全。
如果这里有任何陷阱,那么在某些情况下打印 *p 可能会产生 42。
没有。
编译器如果应用此类优化,则必须意识到您正在修改一个可能通过另一个指针别名的全局变量,并在每次访问时重新计算结果。您可以考虑研究
restrict
关键字。