Nim*_*Nim 10 c++ gcc strict-aliasing placement-new compiler-warnings
我们刚刚将编译器升级到gcc 4.6,现在我们得到了一些警告.目前我们的代码库还没有用c ++ 0x编译的状态,无论如何,我们不想在prod中运行它(至少还没有) - 所以我需要一个修复来删除这个警告.
警告通常是因为这样的事情发生:
struct SomeDataPage
{
// members
char vData[SOME_SIZE];
};
Run Code Online (Sandbox Code Playgroud)
之后,将按以下方式使用
SomeDataPage page;
new(page.vData) SomeType(); // non-trivial constructor
Run Code Online (Sandbox Code Playgroud)
例如,要读取,更新和返回,以下演员曾经发生过
reinterpret_cast<SomeType*>(page.vData)->some_member();
Run Code Online (Sandbox Code Playgroud)
4.4这是可以的; 在4.6中上面生成:
警告:类型惩罚指针将破坏严格别名规则
现在一个删除此错误的干净方法是使用a union,但是就像我说的,我们不能使用c ++ 0x(因此不受限制的联合),所以我使用了下面可怕的黑客 - 现在警告已经消失,但我可能会调用鼻守护进程吗?
static_cast<SomeType*>(reinterpret_cast<void*>(page.vData))->some_member();
Run Code Online (Sandbox Code Playgroud)
这似乎工作正常(请参阅这里的简单示例:http://www.ideone.com/9p3MS)并且不会生成任何警告,这是否正常(不具有文体意义)使用此直到c ++ 0x?
注意:我-fno-strict-aliasing一般不想使用......
编辑:似乎我错了,同样的警告是在4.4,我想我们最近只选择了这个改变(它总是不太可能是一个编译器问题),问题仍然存在.
编辑:进一步调查产生了一些有趣的信息,似乎在一行中进行强制转换和调用成员函数是导致警告的原因,如果代码被分成两行,如下所示
SomeType* ptr = reinterpret_cast<SomeType*>(page.vData);
ptr->some_method();
Run Code Online (Sandbox Code Playgroud)
这实际上不会产生警告.结果,我在ideone上的简单示例是有缺陷的,更重要的是我的hack上面没有修复警告,修复它的唯一方法是从强制转换中分离函数调用 - 然后强制转换可以保留为reinterpret_cast.
SomeDataPage page;
new(page.vData) SomeType(); // non-trivial constructor
reinterpret_cast<SomeType*>(page.vData)->some_member();
Run Code Online (Sandbox Code Playgroud)
4.4 没问题;在 4.6 中,上面生成:
warning: type punned pointer will break strict-aliasing rules
Run Code Online (Sandbox Code Playgroud)
你可以试试:
SomeDataPage page;
SomeType *data = new(page.vData) SomeType(); // non-trivial constructor
data->some_member();
Run Code Online (Sandbox Code Playgroud)