Preferred idiom for endianess-agnostic reads

后端 未结 3 1426
耶瑟儿~
耶瑟儿~ 2021-01-02 09:38

In the Plan 9 source code I often find code like this to read serialised data from a buffer with a well-defined endianess:

#include 

uint32_         


        
相关标签:
3条回答
  • 2021-01-02 10:04

    After some research, I found (with the help of the terrific people in ##c on Freenode), that gcc 5.0 will implement optimizations for the kind of pattern described above. In fact, it compiles the C source listed in my question to the exact assembly I listed below.

    I haven't found similar information about clang, so I filed a bug report. As of Clang 9.0, clang recognises both the read as well as the write idiom and turns it into fast code.

    0 讨论(0)
  • 2021-01-02 10:06

    If you want to guaranty a conversions between a native platform order and a defined order (order on a network for example) you can let system libraries to the work and simply use the functions of <netinet/in.h> : hton, htons, htonl and ntoh, ntohs, nthol.

    But I must admit that the include file is not guaranteed : under Windows I think it is winsock.h.

    0 讨论(0)
  • 2021-01-02 10:18

    You could determine endianess like in this answer. Then use the O32_HOST_ORDER macro to decide whether to cast the byte array to an uint32_t directly or to use your bit shifting expression.

    #include <stdint.h>
    
    uint32_t le32read(uint8_t buf[static 4]) {
        if (O32_HOST_ORDER == O32_LITTLE_ENDIAN) {
            return *(uint32_t *)&buf[0];
        }
        return (buf[0] | buf[1] << 8 | buf[2] << 16 | buf[3] << 24);
    }
    
    0 讨论(0)
提交回复
热议问题