假设我有一个指向易失数据的输入和输出指针.....并且我尝试在它们上使用std::copy
:
uint32_t volatile* input = /* */;
uint32_t volatile* output = /* */;
std::copy(input,input+512,output);
应该编译吗?我的想法是应该这样做,但是它在gcc上失败了,因为它试图使用__builtin_memmove
,它需要指向非易失性数据的指针……链接到Godbolt:https://godbolt.org/z/6yDzqb
所以我想我的问题是:这是标准库中的bug还是不允许编译失败?
答案 0 :(得分:1)
是的,应该编译。 std::copy
被指定为[alg.copy]/2,其行为as if是通过将迭代器解引用到源范围中的每个元素而获得的,而只是将通过将迭代器解引用到相应元素中而获得的值分配给了{目的地范围。可以将volatile std::uint32_t
分配给volatile std::uint32_t
,因为volatile std::uint32_t
不是const
[basic.lval]/7。
此外,请注意,does apparently compile在GCC的主干版本上(至少在Godbolt上可用)。所以我想说这几乎可以肯定是一个错误,并且现在似乎已经解决了……
除此之外,您可能要考虑包括<cstdint>
而不是<stdint.h>
,因为C标准库标头仅在C ++中作为不推荐使用的兼容性功能[depr.c.headers]提供。当您这样做时,请注意以下事实:在全局命名空间中实际上是否可以使用[requirements.headers]/4这些标准标头中声明的实体(例如std::uint32_t
)。因此,您可能要考虑使用std::uint32_t
而不是仅使用uint32_t
等,因为实际上只有前者可以保证存在……