c - 字节序不可知读取的首选习惯用法

标签 c optimization endianness idioms

在 Plan 9 源代码中,我经常发现这样的代码可以从具有明确定义的字节顺序的缓冲区中读取序列化数据:

#include <stdint.h>

uint32_t le32read(uint8_t buf[static 4]) {
    return (buf[0] | buf[1] << 8 | buf[2] << 16 | buf[3] << 24);
}

我希望 gcc 和 clang 都能将这段代码编译成像 amd64 上的这个程序集一样简单的东西:

    .global le32read
    .type le32read,@function
le32read:
    mov (%rdi),%eax
    ret
    .size le32read,.-le32read

但出乎我意料的是,gcc 和 clang 都没有识别出这种模式,而是生成了具有多个移位的复杂程序集。

是否有一种适用于这种操作的习惯用法,既可以移植到所有 C99 实现,又可以跨实现生成良好的(即像上面介绍的那样)代码?

最佳答案

经过一些研究,我发现(在 Freenode 上的##c 中的了不起的人的帮助下),gcc 5.0 将对上述那种模式进行优化。事实上,它将我问题中列出的 C 源代码编译为我在下面列出的确切程序集。

我没有找到关于 clang 的类似信息,所以我提交了一个 bug report . 截至 Clang 9.0 , clang 识别读取和写入习惯用法并将其转换为快速代码。

关于c - 字节序不可知读取的首选习惯用法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25219621/

相关文章:

c - 为什么我们需要 stdin 作为输入函数的文件版本?

arrays - 使用矩阵运算而不是 FOR 循环对元胞数组与索引值进行 bool 比较

java - 我该如何优化这段代码?

java - 将字节流从 java 程序发送到运行 C 的设备

c - 这个指令是什么意思(subl $20,%esp)?

c - 声明为 static const 的结构如何在 RAM 中结束? (在 C 中)

c++ - 内存释放后进程的RES内存会下降吗?

python - 有没有更快的方法来解析这个文本文件?

c - 具有 htonl 和 ntohl 功能的 pdp endian

ada - 读取字节流记录