Любой достойный компилятор сгенерирует точно такую же последовательность на машинном языке для обеих конструкций для любого встроенного типа ( int, floatи т. Д.), Если оператор действительно настолько прост x = x + a; и оптимизация включена . (Примечательно, что GCC -O0, который является режимом по умолчанию, выполняет антиоптимизацию , например, вставляет в память совершенно ненужные хранилища, чтобы гарантировать, что отладчики всегда могут найти значения переменных.)
Однако если утверждение более сложное, они могут быть другими. Предположим f, это функция, которая возвращает указатель, тогда
*f() += a;
звонит fтолько один раз, тогда как
*f() = *f() + a;
называет это дважды. Если fесть побочные эффекты, одно из двух будет неправильным (возможно, второе). Даже если у fнего нет побочных эффектов, компилятор не сможет устранить второй вызов, поэтому последний действительно может быть медленнее.
И поскольку мы говорим здесь о C ++, ситуация совершенно иная для типов классов, которые перегружают operator+и operator+=. Если xэто такой тип, то - до оптимизации - x += aпреобразуется в
x.operator+=(a);
тогда как x = x + aпереводится как
auto TEMP(x.operator+(a));
x.operator=(TEMP);
Теперь, если класс написан правильно и оптимизатор компилятора достаточно хорош, оба будут генерировать один и тот же машинный язык, но это не так точно, как для встроенных типов. Вероятно, это то, о чем думает Страуструп, когда поощряет использование +=.