我最近遇到了一个讨厌的 schrödinbug。在尝试将文件加载到平面内存表示中时,作者编写了如下代码:
class Line final { public:
int stuff[3];
char* data;
}
//...
Line* line = /*...*/;
//Trying to treat line->data like an array. This is *wrong*.
line->data = reinterpret_cast<char*>(line) + 3*sizeof(int);
//...
line->data[0] = /*...*/
line->data[1] = /*...*/
//...
line->data[n] = /*...*/ //"line->data" changes because of this line!
所以,发生的事情是第一行代码基本上设置line->data
为等于&line->data
. 这是一个错误,因为对 所指向的值的任何更改line->data
也可能会更改其line->data
本身所指向的内容!
我当时很奇怪,问题发生需要很长时间。我的理解是,除非使用restrict
(或用于 g++/MSVC __restrict
)进行限定,否则编译器必须假定指针是别名的。因此,如果我设置line->data[0]
为某物,那么它将对下一次访问可见line->data[1]
,并且几乎可以肯定是无效的。然而,在调试器中,更改直到很久以后才可见,并且写入愉快地继续了一段时间。
我猜编译器(在本例中为 MSVC 2013)不认为自别名是可能的。这是允许的吗?