考虑我在这个问题中找到的这个函数:
由于变量
到目前为止还好。
但是,如果您通过值传递
void to_bytes(uint64_t const& x, uint8_t* dest) {
dest[7] = uint8_t(x >> 8*7);
dest[6] = uint8_t(x >> 8*6);
dest[5] = uint8_t(x >> 8*5);
dest[4] = uint8_t(x >> 8*4);
dest[3] = uint8_t(x >> 8*3);
dest[2] = uint8_t(x >> 8*2);
dest[1] = uint8_t(x >> 8*1);
dest[0] = uint8_t(x >> 8*0);
}
由于变量
x
和 dest
可能指向同一块内存,编译器不允许将其优化为单个 qword 移动(每行可能会更改 x
的值)。到目前为止还好。
但是,如果您通过值传递
x
,则这个参数不再有效。事实上,GCC 将其优化为一个简单的 mov
指令,与预期相同:https://godbolt.org/z/iYj1or
然而,clang 没有这样做:https://godbolt.org/z/Hgg5z9
我认为,由于不能保证 x
占用任何堆栈内存,任何在调用函数之前使 dest
指向 x
的尝试都将导致未定义的行为,因此编译器可以假设这永远不会发生。这意味着 clang 在这里错过了一些机会。但我不确定。有人可以澄清吗?
dest
不能指向本地变量,因为它还不存在。可能是漏报了一个优化错误。 - M.Mdest[...]
和x
在x>>...
中是无序的,因此如果它们引用同一对象,则会导致未定义行为。因此,在 C++17 之前进行优化时,x 应该是一个引用。 - Oliv