简体   繁体   中英

memcpy vs pointer casts vs something better

I am decoding a serial protocol. The data is sent from a device in little-endian format over the wire. I have hacked together two different ways of doing it but they both seem very "hacky".

// Example of data that is read in from serial port
unsigned char data[8] = {0xb0,0x00,0x44,0x04,0x4a,0x0f,0x4d,0x30};

// This will pull out the number that I need (on a little-endian machine)
uint16_t a;
a = *(uint16_t*)&data[2];

//So will this, but it makes an extra call to memcpy(). (again, only on a little-endian machine)
uint16_t b;
memcpy((void*)&b,(void*)&data[2],sizeof(b));

I have code that I can plug in to swap bytes for big endian machines

    #ifdef WORDS_BIGENDIAN
    unsigned char *word_ptr;
    word_ptr = &data[2];
    // swap bytes, standard XOR swap algorithm
    word_ptr[0] = word_ptr[0] ^ word_ptr[1];
    word_ptr[1] = word_ptr[1] ^ word_ptr[0];
    word_ptr[0] = word_ptr[0] ^ word_ptr[1];
    #endif /* WORDS_BIGENDIAN */

An older question brought this up: memcpy vs pointer cast for reading BLE sensor float but the accepted answer only confirmed that it could work on certain platforms and comments indicated the behavior was undefined. What is a better way of doing this?

Normal procedure would be:

uint16_t a = data[2] + data[3] * 0x100u;

Some people prefer bitshift instead of multiplication but the result is the same.

The memcpy version probably doesn't "make an extra call to memcpy", memcpy optimization is a pretty basic and widespread compiler feature. But it has different behaviour depending on endianness of the local machine.

The *(uint16_t) * version does cause undefined behaviour as you say.

The XOR swap is considered poor form and it's better to swap using a temporary variable . Write simple and maintanable code and let the compiler do its job.

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