reinterpret_cast会导致未定义的行为吗?

时间:2016-05-09 14:31:11

标签: c++ templates reinterpret-cast

我有一个类模板A,其中包含一个指针容器(T*):

template <typename T>
class A {
public:
   // ... 
private:
   std::vector<T*> data;
};

以及一系列功能:

void f(const A<const T>&);
void g(const A<const T>&);

通过从A<const T>A<T>的演员来调用这些功能是否可以?

A<double> a;
... 
auto& ac = reinterpret_cast<const A<const double>&>(a);
f(ac);

我很确定此代码具有未定义的行为。

在现实生活中使用这种转换是否危险?

2 个答案:

答案 0 :(得分:5)

虽然reinterpret_cast本身可能是未指定的行为,但是在您完成转换后尝试访问参数是未定义的行为。

  

N3337 [basic.lval]/10:   如果程序试图通过以下类型之一以外的glvalue访问对象的存储值,则行为未定义

     

- 对象的动态类型,

     

- 对象的动态类型的cv限定版本,

     

- 与对象的动态类型相似的类型(如4.4中所定义)

     

- 与对象的动态类型对应的有符号或无符号类型

     

- 对应于动态类型的cv限定版本的有符号或无符号类型   对象,

     

- 聚合或联合类型,包括其元素中的上述类型之一或非   静态数据成员(包括递归地,子集合的元素或非静态数据成员)   或包含联盟),

     

- 一种类型,是对象动态类型的(可能是cv限定的)基类类型,

     

- char或unsigned char类型。

你的例子不是上述情况。

答案 1 :(得分:4)

由于A<double>A<const double>是不相关的类型,它实际上是未指定的(最初我认为是未定义的)行为,相应地是,它在现实生活中使用是个坏主意:你永远不知道你可能移植到哪个系统或编译器,改变行为是奇怪的方式。

参考:

5.2.10 / 11:

  

类型T1的左值表达式可以强制转换为“引用”类型   T2“如果可以明确表达类型为”T1的指针“   使用reinterpret_cast转换为“指向T2的指针”类型。那   是,参考演员reinterpret_cast(x)具有相同的效果   转换* reinterpret_cast(&amp; x)与内置&amp; x和*   运算符(类似于reinterpret_cast(x))。

所以他们已将我们重定向到前面的5.2.10 / 7节:

  

可以将对象指针显式转换为对象指针   不同的类型。 ......转换类型的prvalue   “指向T1的指针”到“指向T2的指针”(其中T1和T2为   对象类型以及T2的对齐要求为否   比T1更严格,并回到原来的类型产生   原始指针值。任何其他此类指针的结果   转换未指定。

如果fg是适用于容器的算法,那么简单的解决方案就是将它们更改为适用于范围(迭代器对)的模板算法。