Suppose I have a input and output pointers to volatile data.....and I try to use a std::copy
on them:
uint32_t volatile* input = /* */;
uint32_t volatile* output = /* */;
std::copy(input,input+512,output);
Should this compile? My thought is that it should, but it fails on gcc because it is trying to use __builtin_memmove
which requires pointers to non-volatile data......link to godbolt: https://godbolt.org/z/6yDzqb
So I guess my question is this: Is this a bug in the standard library or is this allowed to fail to compile?
Yes, this should compile. std::copy
is specified [alg.copy]/2 to behave as if the value obtained from dereferencing the iterator to each element in the source range was simply assigned to the value obtained from dereferencing the iterator to the corresponding element in the destination range. A volatile std::uint32_t
can be assigned to a volatile std::uint32_t
because a volatile std::uint32_t
is not const
[basic.lval]/7.
Also, note that this does apparently compile on the trunk version of GCC (at least the one available on godbolt). So I would say this almost certainly was a bug, and it seems to be fixed now…
Apart from all that, you may want to consider including <cstdint>
rather than <stdint.h>
as the C Standard Library headers are only available in C++ as a deprecated compatibility feature [depr.c.headers]. When you do, be aware of the fact that it is unspecified [requirements.headers]/4 whether or not the entities declared in these standard headers, such as std::uint32_t
, are actually available in the global namespace. Thus, you may want to consider using std::uint32_t
rather than just uint32_t
etc. as only the former is actually guaranteed to be there…