Home > front end >  C Same Variable on Left and Right Side of Assignment
C Same Variable on Left and Right Side of Assignment

Time:07-28

Suppose that we have some object, such as std::vector<int> foo.

I know from reading the C docs on self-assignment that foo = foo (although weird) should technically be OK since classes in C are responsible for being self-assignment safe.

However, suppose that I also have some method reverse() that does not modify the input, but instead returns a new vector that is a reversed version of the given argument. I then perform:

foo = reverse(foo);

Would this be OK? I've gone down a pretty deep rabbit hole reading about sequence points and things like that, and TBH my brain is sort of fried now- could anybody offer a more straightforward explanation here? I know that x = x 5 where x is of type int is clearly fine, but I'm wondering how this changes when we're dealing with objects that allocate memory.

In addition, suppose that we had another method reverseMutate() that does mutate the input, and then returns that reversed (mutated) original vector back. I'm even less clear whether

foo = reverseMutate(foo);

is defined behavior.

Thank you so much for the help! I promise I've tried diving into the C docs, and I'm just looking for a more straightforward explanation that doesn't make my brain hurt...

CodePudding user response:

Yes on both counts. Everything is safe.

foo = reverse(foo);

If reverse doesn't mutate foo, then it returns a completely unrelated vector, and that vector is assigned to foo. Those two steps happen in that order. The result of reverse must be fully known before operator= is ever called on foo, for the same reason that if we do bar(baz(1)), the baz call must completely terminate before bar is ever called.

foo = reverseMutate(foo);

This one is a little more exciting but is still fine. If reverseMutate(foo) mutates foo and then returns it (i.e. literally return *this; as a std::vector<int>&), then it behaves the same as

reverseMutate(foo);
foo = foo;

i.e. it's just self-assignment in disguise, and as you've already correctly pointed out, C classes are responsible for being able to handle this case.

  •  Tags:  
  • c
  • Related