我有以下代码,我想知道为什么我有以下输出:
#include <iostream>
int main() {
double nValue = 5;
void *pVoid = &nValue;
short *pInt = static_cast<short*>(pVoid);
std::cout << *pInt << std::endl;
return 0;
}
它输出我'0'。我想知道为什么会这样。谢谢!
我有以下代码,我想知道为什么我有以下输出:
#include <iostream>
int main() {
double nValue = 5;
void *pVoid = &nValue;
short *pInt = static_cast<short*>(pVoid);
std::cout << *pInt << std::endl;
return 0;
}
它输出我'0'。我想知道为什么会这样。谢谢!
您有 UB(未定义行为),因为您违反了指针别名规则。这意味着任何事情都可能发生。
例如,编译器有权期望 ashort*
永远不会引用一个double
对象,因此它几乎可以随心所欲地解释*pInt
。
或者编译器可能会按字面意思解释代码,而在您的平台上,二进制表示5.0
以两个(或sizeof(short)
)字节的零开头。
只是为了好玩,很可能你机器上 5 的双重表示就是这个
*double = (5)
0000000000000000000000000000000000000000000000000000000000000101
^^^^^^^^^^^^^^^^
*short = (0)
这应该告诉你为什么会这样
int main() {
double nValue = 5;
short nValue_short = 5;
std::bitset<sizeof(double)*8> bit_double(nValue);
std::bitset<sizeof(short)*8> bit_short(nValue_short);
std::cout << bit_double << std::endl;
std::cout << bit_short << std::endl;
return 0;
}
double
您正在将带有数据的内存块转换为short
. 由于您在该块中存储了一个小值,因此它不会存储在第一位。因此首先bits
为零。但它依赖于内部double
表示和short
大小,因此不保证在不同平台上相同
您试图将 a 的内容解释double
为 a short
。这会调用未定义的行为——你的程序可以自由地做任何事情。
pVoid
指向代表 a 的位模式double
。一旦使用void*
. 在转换void*
to 时short*
,您声称指向的位模式是 a short
,但事实并非如此。ashort
和 adouble
在内存中的表示是完全不同的。当您取消引用pInt
时,该位置的内存恰好为 0。编译器此时不再知道该值的类型是真的double
,因此如果这是您所期望的,则不可能进行隐式转换。