IIn*_*ble 9 c++ language-lawyer
我的心智模型reinterpret_cast一直是,将表达式的位序列视为不同类型,并且cppreference(注意:这不是C++标准中的引用)似乎同意这一点:
不像
static_cast,但是const_cast,reinterpret_cast表达式不会编译到任何CPU指令.它纯粹是一个编译器指令,它指示编译器将表达式的位序列(对象表示)视为具有new_type类型.
寻找保证,我偶然发现[expr.reinterpret.cast]下的一个注释:
[ 注意:由may执行
reinterpret_cast或可能不执行的映射会生成与原始值不同的表示.- 结束说明 ]
这让我想知道:在哪个条件下reinterpret_cast产生的值与对象表示不同于原始值?
这是一个例子:如果您阅读第4个要点:
指针可以显式转换为足以容纳其类型的所有值的任何整数类型.映射函数是实现定义的.[注意:对于那些了解底层机器的寻址结构的人来说,这并不奇怪. - 结束说明]
现在,它是实现定义的,i这里有什么价值:
void *ptr = <some valid pointer value>;
uintptr_t i = reinterpret_cast<uintptr_t>(ptr);
它可以是任何东西,只要reinterpret_cast荷兰国际集团i前,我们会得到ptr.
表示ptr和i可能不同.标准只是说价值i应该"不足为奇".甚至,如果我们reinterpret_cast ptr使用更宽的整数(例如,如果指针是32位,则转换为unsigned long long int),则表示必须不同,因为变量的大小不同.
所以我认为cppreference描述是误导性的,因为可能有reinterpret_casts,它实际上需要CPU指令.
这是另一个案例(由IInspectable发现),Keith Thompson的评论:
用于Cray向量机的C编译器,例如T90,做类似的事情.硬件地址为8个字节,指向8个字节的字.void*和char*在软件中处理,并在字内增加3位偏移量 - 但由于实际上没有64位地址空间,因此偏移量存储在高位3位64位字.因此char*和int*的大小相同,但具有不同的内部表示 - 并且假定指针"真的"只是整数的代码可能会严重失败.
char *并且int *在Cray T90上有不同的表现形式,所以:
int *i = <some int pointer value>;
char *c = reinterpret_cast<char *>(i);
在这里,i并且c将对Cray T90有不同的表示(并且这种转换肯定使用CPU指令).
(我已经验证了这一点,Cray C/C++参考手册SR-2179 2.0的第3.1.2.7.1章)