在 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 源代码编译为下面列出的确切程序集。
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.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)