有没有办法避免严格的锯齿警告?
我正在使用库(ENet),它使用回调。 在这些回调函数中,它传递一个包含用户数据的void *的结构,供您自己使用。 我想使用该变量,但不是作为指针。 我不想分配内存,所以我可以指出它,我宁愿直接使用void *的空间来存储size_t。
但是,正如所料,当我将void *变量转换为size_t变量时,我得到了严格的别名警告。 回调的结构不提供联合来访问它作为void *之外的其他东西。
我知道我可以完全禁用这个警告,但我宁愿为这个特定的情况保持沉默。 有没有办法编写这种类型的转换,让编译器知道这是故意的,以避免警告?
编辑:
这是我想要做的一个例子。 由于我需要能够编辑用户值,因此我将它转换为size_t,同时试图获取对它的引用:
size_t& offset = reinterpret_cast<size_t&>(packet->userData);
这有效,但给出了警告。
但是,正如所料,当我将void *变量解引用到size_t变量时,我得到了严格的别名警告。
如果你想使用void *
本身来传输一个普通的整数,你不想取消引用它,你想把它转换为适当的整型( intptr_t
是你最好的选择,因为标准保证它可以存活到void *
的往返)。
intptr_t magic=42;
register_callback(&myfunc, (void *)magic);
// ...
void myfunc(void *context)
{
intptr_t magic=(intptr_t)context;
// ...
}
(如果你喜欢C ++风格的演员,那么这些都将是reinterpret_cast
)
此外,你可能在你的代码中做了一些奇怪的事情,因为void *
(比如char *
和unsigned char *
)不会受到严格的别名规则(它们可以别名)。
更新
这是我想要做的一个例子。 由于我需要能够编辑用户值,因此我将它转换为size_t,同时试图获取对它的引用:
size_t& offset = reinterpret_cast<size_t&>(packet->userData);
这有效,但给出了警告。
不,甚至假设size_t
和void *
具有相同的大小和对齐要求(这是不能保证的),这不可能轻易完成; 别名void *&
带有size_t &
是不允许的(另外,这是特别迂回的,因为它隐藏在参考中)。
如果你真的需要这样做,你必须与编译器达成一致。 在gcc中,例如,您可以使用-fno-strict-aliasing
编译文件,而不是简单地禁用警告(隐藏地毯下的潜在问题),禁用编译器关于严格的假设别名,以便生成的代码正常工作,即使指向不相关类型的指针或引用指向相同的东西。
上一篇: Is there a way to avoid the strict aliasing warning?
下一篇: restrict qualifier on member functions (restrict this pointer)