[Я оставляю свой ответ ниже для справки, но дальнейшее обсуждение показало, что мой ответ ниже неполон и что его заключение в конечном итоге неверно.]
Стандарт C ++ 17 (черновик здесь ), [expr.ass], действительно читает:
Правый операнд [оператора присваивания] упорядочен перед левым операндом.
Это звучит так же неправильно для меня, как и для вас.@ Барри не нравится ваш пример кода, поэтому, чтобы не отвлекать вопрос, я проверил альтернативный код:
#include <iostream>
namespace {
int a {3};
int& left()
{
std::cout << "in left () ...\n";
return ++a;
}
int right()
{
std::cout << "in right() ...\n";
return a *= 2;
}
}
int main()
{
left() = right();
std::cout << a << "\n";
return 0;
}
Вывод (с использованием GCC 6.3):
in left () ...
in right() ...
8
Считаете ли вы напечатанныйЕсли рассматривать сообщения или считать вычисленное значение 8, то выглядит, как будто операнд left был упорядочен до операнда right - что имеет смысл, поскольку эффективный машинный код
- обычно предпочитает решить, где хранить вычисленный результат
- , прежде чем вычислять результат.
Я бы не согласился с @Barry.Возможно, вы обнаружили нетривиальную проблему со стандартом.Если у вас есть время, сообщите об этом.
ОБНОВЛЕНИЕ
@ SombreroChicken добавляет:
Это только потому, что GCC 6.3 не правильнореализовать C ++ 17 еще.Начиная с версии 7.1 и далее он оценивает сразу, как показано здесь .
Вывод:
in right() ...
in left () ...
6