【发布时间】:2011-02-20 20:20:40
【问题描述】:
我最近读了很多关于strict aliasing的文章。 C/C++ 标准说以下代码无效(未定义的行为是正确的),因为编译器可能在某处缓存了 a 的值,并且在我更新 b 时不会识别它需要更新该值;
float *a;
...
int *b = reinterpret_cast<int*>(a);
*b = 1;
该标准还规定char* 可以为任何内容设置别名,因此(如果我错了,请纠正我)每当对char* 变量进行写访问时,编译器都会重新加载所有缓存的值。因此下面的代码是正确的:
float *a;
...
char *b = reinterpret_cast<char*>(a);
*b = 1;
但是在根本不涉及指针的情况下呢?例如,我有以下代码,GCC 会向我抛出关于严格别名的警告。
float a = 2.4;
int32_t b = reinterpret_cast<int&>(a);
我想要做的只是复制 a 的原始值,所以不应该应用严格的别名。这里可能存在问题,还是只是 GCC 对此过于谨慎?
编辑
我知道有一个使用 memcpy 的解决方案,但是它会导致代码的可读性大大降低,所以我不想使用那个解决方案。
EDIT2
int32_t b = *reinterpret_cast<int*>(&a); 也不起作用。
已解决
这似乎是a bug in GCC。
【问题讨论】:
-
当你写一个字符指针时,编译器不一定会重新加载所有变量,但它能够找出哪个变量发生了变化,然后重新加载那个变量。
-
你确定最后一个例子给出了警告吗?使用 GCC 4.1.2 (
-Wall -ansi -pedantic) 编译,我没有收到任何投诉。 -
您不会从前两个示例中获得 任何 工作代码,因为您将 int* 隐式分配给 int 并将 char* 分配给 char。跨度>
-
@DeadMG:哎呀,我的错。
-
@Oli Charlesworth:您需要首先使用
-fstrict-aliasing命令行开关或使用-O2启用严格别名
标签: c++ casting reinterpret-cast strict-aliasing type-punning