Is there a way of preventing a C++ compiler from optimizing a copy of a temporary rvalue into a move operation?

115 Views Asked by At

eg:

std::vector<int> i;
i = std::vector{5, 4, 3, 2, 1}

In the above case, a compiler will typically optimize the second line into a move operation instead of a copy operation despite the lack of a std::move() enclosure. This is normally fine, but in some cases can cause issues, for example, if i is declared with a particular allocator, the semantics of what happens with the destination allocator is very different, depending on whether or not the operation is a copy or a move (if the vector implementation is standards-compliant, that is). Let's ignore that the above is Bad Code ie. it should be one line, without the needless construction of a secondary vector and focus on the other problem.

We could hypothesize other use-cases where moving is designed to do something slightly different with container metadata. Say we have a struct:

struct t
{
   int data;
   int usage;

   // Methods and constructors etc go here
};

And the usage variable tells us how many times the data has been accessed by a given method. Semantically, a copy operation would probably simply copy the data variable from one struct instance to another. A move operation would want to replace the usage variable as well, as it is effectively moving the entire state of one struct instance to another. Ignore whether or not you think this is unlikely, it's just a hypothetical example for illustration purposes.

Now, if someone writes some bad code eg.:

t a;
// Some accesses of a's data member occur here via a member function.

t b = 4;
a = b;
// b is not used after this point.

The compiler may optimize b into a temporary, and optimize a = b into a move operation. As noted, this could cause problems.

So. Is there a way - from the writer of the struct's side - to write operator = methods such that both copy assignment and move assignment are possible, but that the C++ compiler cannot optimize the copy operation into a move operation - even if a temporary rvalue is used? I'm aware this can be prevented by the writer of the code using t, but I'm interested in fool-proofing code in this particular case.

Thanks-

0

There are 0 best solutions below