在2019年5月之前(可能更晚)发布的GCC版本无法优化这段代码:
// Replace the k'th byte within an int
int replace_byte(int v1 ,char v2, size_t k)
{
memcpy( (void*) (((char*)&v1)+k) , &v2 , sizeof(v2) );
return v1;
}
可以看出here(GodBolt):clang优化了这段代码,GCC和MSVC没有。这是GCC bug 90271,在某些时候将被修复。但是 - 今天的GCC版本不会修复,今天我想编写这段代码......
那么:是否有一种解决方法可以使GCC为这个函数生成与clang相同的代码,或者至少 - 性能相当的代码,将数据保存在寄存器中而不是求助于指针和堆栈?
笔记:
这使得非内联版本更长一些,但内联版本针对所有三个编译器进行了优化:
int replace_bytes(int v1 ,char v2, size_t k)
{
return (v1 & ~(0xFF << k * 8)) | ((unsigned char)v2 << k * 8);
}
如果v2
是签名类型,那么在转换前unsigned char
到char
的演员是必要的。在这种情况下,如果没有这种情况,v2
将被符号扩展为整数,这将导致结果中不需要的位设置为1。