这个黑客是否删除别名警告UB?

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.

cur*_*guy 2

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)