c++ - c/c++中endian的最佳和可移植转换

标签 c++ optimization endianness

给定一个包含我需要解析的 32 位小端字段的二进制文件,我想编写能够正确编译的解析代码,而与执行该代码的机器的端序无关。目前我在用

uint32_t fromLittleEndian(const char* data){
  return uint32_t(data[3]) << (CHAR_BIT*3) |
         uint32_t(data[2]) << (CHAR_BIT*2) |
         uint32_t(data[1]) << CHAR_BIT |
         data[0]; 
}

然而,这会产生非最佳装配。在我的机器上 g++ -O3 -S 产生:

_Z16fromLittleEndianPKc:
.LFB4:
    .cfi_startproc
    movsbl  3(%rdi), %eax
    sall    $24, %eax
    movl    %eax, %edx
    movsbl  2(%rdi), %eax
    sall    $16, %eax
    orl %edx, %eax
    movsbl  (%rdi), %edx
    orl %edx, %eax
    movsbl  1(%rdi), %edx
    sall    $8, %edx
    orl %edx, %eax
    ret
    .cfi_endproc

为什么会这样?我怎样才能说服它在小端机器上编译时生成最佳代码:

_Z17fromLittleEndian2PKc:
.LFB5:
    .cfi_startproc
    movl    (%rdi), %eax
    ret
    .cfi_endproc

这是我通过编译得到的:

uint32_t fromLittleEndian2(const char* data){
    return *reinterpret_cast<const uint32_t*>(data);
}

因为我知道我的机器是小端,所以我知道上面的汇编是最优的,但是如果在大端机器上编译它会失败。它还违反了严格的别名规则,因此如果内联它甚至在小端机器上也可能产生 UB。 如果可能的话是否有一个有效的代码将被编译成最佳汇编?

因为我希望我的函数内联很多,所以任何类型的运行时字节序检测都是不可能的。编写最佳 C/C++ 代码的唯一替代方法是使用编译时字节序检测,如果目标字节序,则使用 template#define 回退到低效代码不是小端。然而,这似乎很难便携地完成。

最佳答案

简短的回答 - 使用 htonl - 它会被 wazzoo 优化

关于c++ - c/c++中endian的最佳和可移植转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36657895/

相关文章:

css - 优化网站上加载的资源

c++ - 将 n 维 "square"空间划分为立方体

c++ - C/C++ : Force Bit Field Order and Alignment

c++ - 在编译时确定继承

python - Django get() 是否对values() 执行数据库查询?

c++ - QStyledItemDelegate::paint - 为什么我的文本没有正确对齐?

c - 如何从内存中读取16位值

python - uint8 小端数组到 uint16 大端

c++ - 使用 "constexpr"将字符串文字用于模板参数

c++ - IRQ 处理程序三重故障