【发布时间】:2010-06-05 15:23:43
【问题描述】:
我遇到了一个由违反严格的指针别名规则引起的问题。我有一个来自模板的类型T 和一些相同大小的整数类型Int(与sizeof 一样)。我的代码基本上执行以下操作:
T x = some_other_t;
if (*reinterpret_cast <Int*> (&x) == 0)
...
因为T 是一些可以有构造函数的任意(大小限制除外)类型,所以我不能将T 和Int 合并。 (这仅在 C++0x 中允许,甚至 GCC 还不支持)。
有什么方法可以重写上面的伪代码来保留功能并避免违反严格的别名规则?请注意,这是一个模板,我无法控制T 或some_other_t 的值;赋值和后续比较确实发生在模板代码中。
(作为记录,如果T 包含任何位字段,上述代码在 GCC 4.5 上开始中断。)
【问题讨论】:
-
你想做什么?我想不出该代码有意义的许多情况。它当然没有被标准很好地指定。因此,假设这个 hack 确实是必要的(它可能不是),你可能只需要使用适当的编译器标志来禁用严格的别名。
-
@jalf:这是一个独特的容器。我用整数 0 标记空位置。但是,由于
T可以是任何值,包括按位 0,我最多需要将一个位置标记为“非空,即使它看起来像空”。比较是检查是否应该标记x。 -
我不清楚你是如何解决这个问题的 -
reinterpret_cast如何让你忽略存储0的两个不同原因? -
@doublep:这还不完全清楚。您实际上是在尝试测试
x在内存中是否由全零表示? -
@Stephen:如果两个
T与==不相等,则它们不能按位相等,至少对于容器相等定义中的任何有用。因此,唯一容器中不能有两个按位为零的元素(如果相等是合理的)。
标签: c++ generics reinterpret-cast strict-aliasing type-punning