试图理解为什么我从程序中得到以下输出:
$ ./chartouintest
UInts: 153 97 67 49 139 0 3 129
Hexes: 99 61 43 31 8b 00 03 81
uint64 val: 8103008b31436199
$
我试图只输出实际的UInt64数值,但似乎无法做到(输出不正确)
这是代码:
#include <iostream>
#include <iomanip>
#include <stdlib.h>
union bytes {
unsigned char c[8];
uint64_t l;
} memobj;
int main() {
//fill with random bytes
for(unsigned int i=0; i < sizeof(memobj.c); ++i) { memobj.c[i] = (unsigned char)rand();}
//see values of all elements as unsigned int8's and hex vals
std::cout << "UInts: ";
for (int x=0; x < sizeof(memobj.c); ++x) { std::cout << (unsigned int)memobj.c[x] << " "; }
std::cout << std::endl;
std::cout << "Hexes: ";
for (int x=0; x < sizeof(memobj.c); ++x) { std::cout << std::setw(2) << std::setfill('0') << std::hex << (unsigned int)memobj.c[x] << " "; }
std::cout << std::endl;
std::cout << "uint64 val: " << memobj.l << std::endl;
}
我做错了什么???提前感谢您的帮助!
J
写入联合的一个成员并读取另一个成员是未定义的行为(有例外,但在本例中是UB)。
你不应该期望任何东西。编译器可以对代码执行它想要的WTF,例如在调试模式下给出一个好的"预期"结果,在发布模式下给出垃圾或崩溃。当然,另一个编译器可能会玩另一个把戏。你永远不会确定,为什么要麻烦呢?
为什么不以正确的方式来做呢?也许是memcpy
?
编辑:
要想真正回答这个问题,请注意std::cout
:std::hex
将流设置为十六进制表示,这就是为什么最后的"uint64 val:"显示以十六进制为基础(而不是OP所期望的十进制)。除此之外,输出没有任何问题,尽管UB有威胁。