[英]best way to concatenating and splitting uint32_t to/from uint64_t
這段代碼怎么樣
#include <cstdio>
#include <cinttypes>
#include <type_traits>
#include <cstddef>
#include <iostream>
int main()
{
uint64_t tsc = 0xdeaddeadc0dec0de;
uint32_t MSB = *((uint32_t*)&tsc+1);
uint32_t LSB = *((uint32_t*)&tsc);
std::printf("low %x high %x \n", LSB,MSB);
uint64_t MLSB = 0;
*((uint32_t*)&MLSB) = LSB;
*((uint32_t*)&MLSB+1) = MSB;
std::printf("highlow %lx \n", MLSB);
uint64_t LMSB = 0;
*((uint32_t*)&LMSB+1) = LSB;
*((uint32_t*)&LMSB) = MSB;
std::printf("lowhigh %lx \n", LMSB);
}
問題 go 這段代碼有什么問題? 它是否依賴於機器成為大端? 可能是。 所以對於 Little-endian LSB 和 MSB 位置會改變,或者你可以通過使用系統宏使它自動進行轉變和類型鑄造?
如果您認為必須在代碼中處理字節順序,那您就大錯特錯了。
uint64_t tsc = 0xdeaddeadc0dec0de;
uint32_t MSB = tsc >> 32;
uint32_t LSB = tsc;
uint64_t MLSB = LSB | (static_cast<uint64_t>(MSB)) << 32;
uint64_t LMSB = MSB | (static_cast<uint64_t>(LSB)) << 32;
這就是您所需要的。 數字就是數字。 他們沒有字節順序。 數字表示具有字節順序。 不要處理表示,處理數字。
有關更多信息,請閱讀字節順序謬誤。
由於所謂的嚴格別名規則,C++ 中的類型雙關是不允許的。
此外,該代碼在大端或中端機器上根本無法運行。
一個簡單正確的解決方案是使用位移:
uint64_t tsc = 0xdeaddeadc0dec0de;
uint32_t MSB = (uint32_t)(tsc >> 32);
uint32_t LSB = (uint32_t)(tsc);
std::printf("low %x high %x \n", LSB, MSB);
uint64_t MLSB = ((uint64_t)MSB << 32) | LSB;
std::printf("highlow %lx \n", MLSB);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.