简体   繁体   中英

In C++, is A+=B preferable to A=A+B in the same way ++A is to A++?

In C++, is A+=B preferable to A=A+B in the same way ++A is to A++?

I understand that a "++A" preincrement is guaranteed to be at least as fast as a "A++" postincrement. This is discussed many places including here and here . Likewise, A+=B is expected to be at least as fast as A=A+B, as here .

I was looking at this for ++:

//From https://herbsutter.com/2013/05/13/gotw-2-solution-temporary-objects/
T T::operator++(int)() {
auto old = *this; // remember our original value
++*this;          // always implement postincr in terms of preincr
return old;       // return our original value
}

My reasoning is that in the worst case (probably from complex object types) A=A+B would have to retrieve and store A and add in B before saving it back to the original A location, while A+=B would take B and add it to A directly. Is my reasoning correct?

It is expected that basic types are rearranged as the same at compile time, and that this really only applies to complex objects requiring operator overloading.

Does this extend generically to most imperative languages?

I would say the reasons aren't quite the same. My main reason for prefering A += B over A = A + B is conciseness. A += B clearly states that you want to add B to A. This is especially true if A is a more complex expression:

node_capacities[std::make_pair(node1,node2)] += edge.capacity;

I've never found the performance of A += B to be worse than A = A + B either.

The big thing to remember is that C++ have operator overloading which means that te += operator can mean something completely different from what you expect.

The += operator only works as add and assign to if the "destination" class doesn't have an += operator defined for it. Operator overloading also means that eg x++ can mean different thing depending on what the class instance of x defines for operator overloads.

You should prefer A += B; .

If you ever wrote a type where A = A + B; turned out to be better than A += B; , then you should change the implementation of operator+= to do exactly what A = A + B; does.

However, the reverse generally can't be done; you usually can't modify operator+ in any reasonable fashion to make A = A + B; do exactly the same thing as A += B; .

Thus, if there is a difference between A += B; and A = A + B; , you should expect A += B; to be the better choice.

In most cases, A+=B is preferable. As you have pointed out, there would be more register loads in A = A + B vs A+=B. Also of interest might be to read up on SSA . This is used in compiler optimization, and might help understand how such case is dealt with. As you have said, most of these considerations are taken out of the programmers hands thanks to the compiler, but it is good to be aware of these things.

Another consideration to account for in complex objects is the possible side effects caused by calling getters, and the fallout for calling such getter twice. (Think, A.get() = A.get() + B.get()). This however should be relatively rare, since getters should not have side effects in most cases.

In fact, in C++ you should avoid postfixed operators:

  • ++a //here the operator ++ is prefixed
  • a++ //here the operator ++ is postfixed

Just because the postfixed solution will use the value of a then increase its value, which can be dangerous some times, or at least decrease some performances.

You can take a look here for further informations.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM