pet*_*ohn 53 c++ warnings strict-aliasing
我使用一个代码,我将枚举*转换为int*.像这样的东西:
enum foo { ... }
...
foo foobar;
int *pi = reinterpret_cast<int*>(&foobar);
Run Code Online (Sandbox Code Playgroud)
在编译代码(g ++ 4.1.2)时,我收到以下警告消息:
dereferencing type-punned pointer will break strict-aliasing rules
Run Code Online (Sandbox Code Playgroud)
我用Google搜索了这条消息,发现只有在严格的别名优化打开时才会发生这种情况.我有以下问题:
是的,我实际上需要这种别名.
moo*_*dow 57
为了:
是.GCC将假设指针不能别名.例如,如果你通过一个分配,然后从另一个读取,GCC可以作为优化,重新排序读取和写入 - 我已经看到这发生在生产代码中,并且调试不愉快.
一些.您可以使用联合来表示需要重新解释的内存.你可以用一个reinterpret_cast.您可以char *在重新解释内存的位置强制转换 - char *定义为能够为别名设置别名.你可以使用一个类型__attribute__((__may_alias__)).您可以使用-fno-strict-aliasing全局关闭别名假设.
__attribute__((__may_alias__)) 对于使用的类型,可能是最接近禁用特定代码段的假设.
对于您的特定示例,请注意枚举的大小定义不正确; GCC通常使用可用于表示它的最小整数大小,因此将指向枚举的指针重新解释为整数可能会在结果整数中留下未初始化的数据字节.不要那样做.为什么不直接转换为适当大的整数类型?
Cas*_*Cow 11
但你为什么要这样做?如果sizeof(foo)!= sizeof(int),它将会中断.仅仅因为枚举就像一个整数并不意味着它被存储为一个整数.
所以,是的,它可能会产生"潜在的"错误代码.
小智 11
您可以使用以下代码来转换数据:
template<typename T, typename F>
struct alias_cast_t
{
union
{
F raw;
T data;
};
};
template<typename T, typename F>
T alias_cast(F raw_data)
{
alias_cast_t<T, F> ac;
ac.raw = raw_data;
return ac.data;
}
Run Code Online (Sandbox Code Playgroud)
用法示例:
unsigned int data = alias_cast<unsigned int>(raw_ptr);
Run Code Online (Sandbox Code Playgroud)