reinterpret_cast 向上转换指针的整数
reinterpret_cast integer to pointer with upcast
下面的代码安全吗:
#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 说一个可以:
- reinterpret_cast 从 B* 到 std::uintptr_t
- reinterpret_cast从std::uintptr_t到B*(因为来回是同一类型)
- reinterpret_cast 从 B* 到 A*
那么,合并最后两个是否安全?
在那种特殊情况下,代码是安全的。那是因为 upcasting 的安全性。这总是允许 public 继承, 没有显式类型转换 。
简而言之,您只是强制执行某些可能被视为隐含的内容。
带uintptr_t
的B
类型地址的通道也是无用的,但允许因为“相同类型”。
编辑
关于 uintptr_t
。
Integer type capable of holding a value converted from a void pointer and then be converted back to that type with a value that compares equal to the original pointer.
注意“比较等于原来的指针”。
我不知道 "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 说一个可以:
- reinterpret_cast 从 B* 到 std::uintptr_t
- reinterpret_cast从std::uintptr_t到B*(因为来回是同一类型)
- reinterpret_cast 从 B* 到 A*
那么,合并最后两个是否安全?
在那种特殊情况下,代码是安全的。那是因为 upcasting 的安全性。这总是允许 public 继承, 没有显式类型转换 。
简而言之,您只是强制执行某些可能被视为隐含的内容。
带uintptr_t
的B
类型地址的通道也是无用的,但允许因为“相同类型”。
编辑
关于 uintptr_t
。
Integer type capable of holding a value converted from a void pointer and then be converted back to that type with a value that compares equal to the original pointer.
注意“比较等于原来的指针”。
我不知道 "safe" 是什么意思,但是使用此代码的程序的行为是未定义的。您可以将指针转换为大到足以容纳该值的整数类型,并且可以将该值转换回与原始类型相同的指针。问题中的代码没有这样做:它将值转换为指针 ,其类型与原始 .
不同