reinterpret_cast整数到指向upcast的指针

时间:2016-08-19 13:16:46

标签: c++ casting c++14 reinterpret-cast

以下代码是否安全:

#include <iostream>
#include <cstdint>

struct A{
  int i = 0;
  virtual int foo() {return i;}
};
struct B : A{
  int foo() override {return i+2;}
};

using handle_t = std::uintptr_t;
handle_t get(B& a){
  return reinterpret_cast<handle_t>(&a);
}

void use(handle_t h){
  auto p= reinterpret_cast<A*>(h); // 
  std::cout << p->foo() << "\n";
}

int main(int argc, char *argv[])
{
  B a;
  auto h = get(a);
  use(h);
  return 0;
}

CppReference's page说可以:

  • 从B * reinterpret_cast到std :: uintptr_t
  • 从std :: uintptr_t到B *的reinterpret_cast(因为来回的类型相同)
  • 从B * reinterpret_cast到A *

那么,合并最后两个是否安全?

2 个答案:

答案 0 :(得分:1)

我不知道&#34;安全&#34;表示,但使用此代码的程序的行为是未定义的。您可以将指针转换为足以保存该值的整数类型,并且可以将该值转换回指针,其类型与原始相同。问题中的代码不会这样做:它将值转换为指针,其类型与原始不同。

答案 1 :(得分:-1)

在特定情况下,代码是安全的。那是因为 upcasting 的安全性。这总是允许公共继承,没有明确的类型转换

总之,你只是强迫某些东西可以被认为是隐含的。

使用B传递uintptr_t类型的地址也没用,但是因为“相同的类型”而被允许。

修改

关于uintptr_t

  

整数类型,能够保存从void指针转换的值,然后转换回该类型,其值与原始指针的值相等。

注意“比较等于原始指针”。