Search code examples
c++castingc++14reinterpret-cast

reinterpret_cast integer to pointer with upcast


Is the following code safe :

#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 says one can :

  • reinterpret_cast from B* to std::uintptr_t
  • reinterpret_cast from std::uintptr_t to B* (because it's the same type back and forth)
  • reinterpret_cast from B* to A*

So, is it safe to merge the last two ?


Solution

  • I don't know what "safe" means, but the behavior of a program that uses this code is undefined. You can convert a pointer into an integer type that's large enough to hold the value, and you can convert that value back into a pointer with the same type as the original. The code in the question doesn't do that: it converts the value into a pointer with a different type from the original.