代码如下:
#include <cstring>
#include <cstdint>
#include <cstddef>
uint64_t uint5korr(const std::byte *p)
{
uint64_t result= 0;
std::memcpy(&result, p, 5);
return result;
}
这里的clang将result
优化为寄存器,而gcc则没有。
我怀疑这可能与我使用变量的地址有关,因为我不能使用寄存器的地址。
这仅仅是gcc缺少优化还是clang某种程度上违反了标准?
答案 0 :(得分:1)
是的,此优化是合法的。从正确的地址读取5个字节(不是8个字节);无需再次存储它们,只需阅读return
,已收地址或否的地址即可。我与迈克尔·肯泽尔(Michael Kenzel)对此表示怀疑,认为它已经定义了行为,但这只能巩固优化的有效性。
答案 1 :(得分:1)
不是language-lawyer答案。
虽然在GCC中似乎确实缺少优化本身,但是使用部分memcpy
ed值IIUC却是不确定的行为。我会向GCC提交错误,以就此问题获得明确的答复。
通过GCC / Clang / MSVC完美优化的方式来加载40位宽度的整数:
std::uint64_t load_u40(const std::byte *p)
{
std::uint8_t lo = 0;
std::memcpy(&lo, p, 1);
std::uint32_t hi = 0;
std::memcpy(&hi, p + 1, 4);
return (static_cast<std::uint64_t>(hi) << 8) | lo;
}