Search code examples
c++stllanguage-lawyervolatile

std::copy on pointers to volatile data


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?


Solution

  • 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…