将指针向量重新解释为常量指针向量是否安全?

11

这种类型转换是否安全?

vector<int*> a;
const vector<const int*>& b = reinterpret_cast<const vector<const int*>&>(a);

在这种情况下,静态转换显然不起作用,因为模板参数正在改变。但是通过执行此重新解释转换,我只是为实质上相同的类型添加了constness。那么这对于所有实际目的来说应该是安全的吗?


2
它可能会出现实际错误的一种方式(虽然我还没有通过测试确认),就是严格别名。优化器有权假定 b 不引用与 a 相同的内存(因为它具有不兼容别名的类型)。然后,优化器将发挥其技巧,您可能会发现它重新排序或省略了一些东西,如果 ab 有效地 引用相同的内存,则不会重新排序或省略这些内容。因此,相同的布局是必要但不足以使其“工作”的条件。 - Steve Jessop
1
另一种看待它的方式是,将reinterpret_cast转换为引用或指针类型的结果基本上是无用的,并且除了转换回原始类型之外,不适用于任何其他操作,除非(a)目标类型对于别名实际对象的类型是合法的,或者(b)您有一些特定的保证来支持您正在进行的特定操作。当两者都不适用时,请勿通过任何类型引用对象,而不是其自身。这样做也称为“类型游戏”。 - Steve Jessop
1个回答

8

像任何使用reinterpret_cast将引用转换为不相关类型的操作一样,它会产生未定义的行为,因此除非您将“安全”定义为“在我的编译器上工作”,否则它不是安全的。


假设任何指针的向量具有相同的结构,这样不就可以了吗?毕竟它们只是地址。或者由于指针的类型而实际上改变了结构。 - user1353535
3
不,库的实现可以任意地专门化模板。不需要不同的专门化版本兼容布局。 - Mike Seymour
“安全”的另一个定义是,“能够在编写时存在的所有编译器上工作”。这个定义比你的定义更强,虽然对于这段代码来说可能是这样,但当然仍然是未定义行为。 - Steve Jessop
@SteveJessop:是的,如果你准备测试所有的内容,那么你可以使用这个定义。 - Mike Seymour
@MikeSeymour:关于那个定义的实际应用,可以“安全地”假设在C++03中字符串存储是连续的。虽然这并不是通过我测试所有的情况来确立的,而是在C++0x委员会会议上进行了一次非正式调查所得出的结论。 - Steve Jessop
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接