有没有办法避免严格的锯齿警告?

我正在使用库(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_tvoid *具有相同的大小和对齐要求(这是不能保证的),这不可能轻易完成; 别名void *&带有size_t &是不允许的(另外,这是特别迂回的,因为它隐藏在参考中)。

如果你真的需要这样做,你必须与编译器达成一致。 在gcc中,例如,您可以使用-fno-strict-aliasing编译文件,而不是简单地禁用警告(隐藏地毯下的潜在问题),禁用编译器关于严格的假设别名,以便生成的代码正常工作,即使指向不相关类型的指针或引用指向相同的东西。

链接地址: http://www.djcxy.com/p/64047.html

上一篇: Is there a way to avoid the strict aliasing warning?

下一篇: restrict qualifier on member functions (restrict this pointer)