Порядок оценки аргументов с использованием std:: cout

Привет всем, что я наткнулся на этот кусок кода сегодня, и я смущен относительно того, что именно происходит и более конкретно в каком порядке:

Код:

#include <iostream>

bool foo(double & m)
{
    m = 1.0;
    return true;
}

int main()
{
    double test = 0.0;
    std::cout << "Value of test is : \t" << test << "\tReturn value of function is : " << foo(test) <<  "\tValue of test : " << test << std::endl;
    return 0;
}

Вывод:

Value of test is :      1       Return value of function is : 1 Value of test : 0

Увидев это, я бы предположил, что перед вызовом функции печатается правильный аргумент. Так что это право на левую оценку? Во время отладки, хотя кажется, что функция вызывается перед выходом, что я и ожидал. Я использую Win7 и MSVS 2010. Любая помощь приветствуется!

Ответ 1

Порядок оценки элементов в выражении неуточнен (кроме некоторых очень частных случаев, таких как операторы && и || и тройной оператор, которые вводят точки последовательности); поэтому не гарантируется, что test будет оцениваться до или после foo(test) (который его модифицирует).

Если ваш код зависит от конкретного порядка оценки, самым простым методом его получения является разделение выражения на несколько разделенных операторов.

Ответ 2

Порядок оценки неуточнен. Это не слева направо, справа налево или что-то еще.

Не делайте этого.

Ответ 3

Ответ на этот вопрос изменился на С++ 17.

Оценка перегруженных операторов теперь упорядочена так же, как и для встроенных операторов (С++ 17 [over.match.oper]/2).

Кроме того, операторы <<, >> и subscriptip теперь имеют левый операнд, упорядоченный до правого, и постфиксное выражение вызова функции секвенируется перед оценкой аргументов.

(Остальные двоичные операторы сохраняют предыдущую последовательность, например + все еще не подвержены изменениям).

Таким образом, код в вопросе должен теперь выводиться. Value of test is: 0 Return value of function is: 1 Value of test: 1. Но совет "Не делай этого" по-прежнему разумен, учитывая, что потребуется некоторое время для обновления до С++ 17.

Ответ 4

Порядок оценки не указан, см. http://en.wikipedia.org/wiki/Sequence_point

Это та же ситуация, что и пример с примером оператора +:

Рассмотрим две функции f() и g(). В C и С++ оператор + не связан с точкой последовательности, поэтому в выражении f()+g() возможно, что сначала будут выполняться либо f(), либо g().