简体   繁体   中英

best way to concatenating and splitting uint32_t to/from uint64_t

How about this code

#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);
}

question what could go wrong in this code? dose it have dependency on machine to be big-endian? probably yes. so for Little-endian LSB and MSB places will change or you can make it automatic by using system macros that give you the Endianness to decide which one is high or low and last if this code works faster and dose it worth it to do this instead of shift and type casting?

If you think you have to deal with endianness in your code, you are doing it totally wrong.

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;

This is all you need. Numbers are numbers. They don't have endianness. Number representation has endianness. Don't work with the representation, work with the numbers.

For more information, read The byte order fallacy .

Type punning in C++ is not allowed due to the so-called strict aliasing rule .

Also, the code won't work at all on a big-endian or middle-endian machine.

An easy correct solution is to use bit-shifting:

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);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM