我想知道,在循环块内部是否可以重复使用指向变量的指针。
int *ptr = nullptr;
for (int i = 0; i < 5; ++i) {
int j = 5;
if (!ptr) ptr = &j;
cout << *ptr << endl;
}
我相信这个代码可以在所有编译器上运行,但它符合标准吗?
j
会被放置在与先前迭代j
完全相同的内存地址上,因此,我认为这在大多数现代编译器中实际上会起作用。但是,是的,这是未定义的行为,不符合标准。 - alexeykuzmin0
&j
替代ptr
,就可以避免这种问题。 - Ed Healint j = 5; int* ptr = &j; cout << *ptr << endl;
(cout
重复5次)。然后,如果在任何其他地方都没有使用ptr
,它将简单地生成cout << 5 << endl;
(重复五次)。请参见此帖子,但尤其要阅读此帖子中的评论。您的假设已经被打破(在那种情况下)。 - Adriano Repettii
计算j
并且使用*ptr
而不是函数调用,则示例会更好。然后,合理的优化程序可以展开循环,并可能重叠计算j
(和/或将某些计算视为从未使用),但无论如何都可能不会将它们全部放在同一位置。 - JSFj
的另一个迭代放在不同的位置,还必须销毁放置在第一个j
的陈旧位置的5
。理论上,那个5
不应该还在那里,但实际上它会存在。因此,即使编译器展开循环并重叠工作以使所有j
不能放在同一位置,陈旧的5
仍然可以代替每个有效的5
。无论多么健壮,它仍然是未定义的。但是,一个不太健壮的版本会更好地解决这个问题。 - JSF