Порядок оценки в параметрах функции С++

Если у нас есть три функции (foo, bar и baz), которые составлены так...

foo(bar(), baz())

Есть ли какая-либо гарантия по стандарту С++, который будет оцениваться баром до baz?

Ответ 1

Нет, нет такой гарантии. Он не определен в соответствии со стандартом C++.

Бьярне Страуструп также прямо говорит об этом в "Языке программирования C++" в разделе 6.2.2 третьего издания с некоторыми соображениями:

Улучшенный код может быть сгенерирован при отсутствии ограничений на порядок оценки выражений

Хотя технически это относится к более ранней части того же раздела, где говорится, что порядок оценки частей выражения также не определен, т.е.

int x = f(2) + g(3);   // undefined whether f() or g() is called first

Ответ 2

Нет никакого определенного порядка для bar() и baz() - единственное, что Стандарт говорит, что они оба будут оценены до вызова foo(). Из стандарта С++, раздел 5.2.2/8:

Порядок оценки аргументов не указано.

Ответ 3

Из [5.2.2] Вызов функции

Порядок оценки аргументов неуточнен. Все побочные эффекты оценок выражения аргументов вступают в силу до ввода функции.

Поэтому нет гарантии, что bar() будет выполняться до baz(), только bar() и baz() будут вызваны до foo.

Также обратите внимание на [5] Выражения, что:

за исключением случаев, отмеченных [например, специальные правила для && и ||], порядок оценки операндов отдельных операторов и подвыражений отдельных выражений и порядок, в котором происходят побочные эффекты, не определены.

так что даже если бы вы спрашивали, будет ли bar() работать до baz() в foo(bar() + baz()), порядок все еще не указан.

Ответ 5

В С++ 11 соответствующий текст можно найти в 8.3.6 Аргументы по умолчанию /9 (Emphasis mine)

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

То же словоблудие используется также стандартом С++ 14 и находится в в том же разделе.

Ответ 6

Как уже отмечалось ранее, стандарт не дает никаких указаний относительно порядка оценки для этого конкретного сценария. Затем этот порядок оценки передается компилятору, и у компилятора может быть гарантия.

Важно помнить, что стандарт С++ - это действительно язык для инструктирования компилятора о построении сборки/машинного кода. Стандарт - это только одна часть уравнения. В тех случаях, когда стандарт является неоднозначным или конкретно определенная реализация, вы должны обратиться к компилятору и понять, как он переводит инструкции С++ в настоящий машинный язык.

Итак, если порядок оценки является требованием или, по крайней мере, важным и совместимым с кросс-компилятором, не является обязательным требованием, исследуйте, как ваш компилятор в конечном итоге сочтет это вместе, ваш ответ может окончательно лежать там. Обратите внимание, что компилятор может изменить его методологию в будущем