Если у нас есть три функции (foo, bar и baz), которые составлены так ...
foo(bar(), baz())
Есть ли гарантия по стандарту C ++, что bar будет оценен до baz?
Нет, такой гарантии нет. Он не определен в соответствии со стандартом C ++.
Бьярн Страуструп также прямо говорит об этом в разделе 6.2.2 3-го издания «Язык программирования C ++», с некоторыми аргументами:
Лучший код может быть сгенерирован без ограничений на порядок оценки выражений
Хотя технически это относится к более ранней части того же раздела, в которой говорится, что порядок оценки частей выражения также не определен, т.е.
int x = f(2) + g(3); // unspecified whether f() or g() is called first
Из [5.2.2] Вызов функции,
Следовательно, нет никакой гарантии, что он
bar()
будет запущен раньшеbaz()
, только тоbar()
иbaz()
будет вызываться раньшеfoo
.Также обратите внимание на [5] Expressions, что:
так что даже если вы спрашивали ли
bar()
будет работать , прежде чемbaz()
вfoo(bar() + baz())
порядок до сих пор не определен.источник
&
,&&
гарантирует оценку слева направо: второй операнд не оценивается, если первый операндfalse
.»Нет определенного порядка для bar () и baz () - единственное, что говорит Стандарт, это то, что они оба будут оценены до вызова foo (). Из стандарта C ++, раздел 5.2.2 / 8:
источник
bar
, затем строку 1baz
, затем строку 2bar
и т. Д.), Что тоже хорошо. :-)C ++ 17 определяет порядок оценки для операторов, который не был указан до C ++ 17. См. Вопрос Каковы гарантии порядка оценки, введенные в C ++ 17? Но обратите внимание на ваше выражение
еще не определен порядок оценки.
источник
В C ++ 11 соответствующий текст можно найти в 8.3.6 Аргументы по умолчанию / 9 (выделено мной)
Такое же словоблудие используется и в стандарте C ++ 14, и его можно найти в том же разделе .
источник
Как уже отмечали другие, стандарт не дает никаких указаний по порядку оценки для этого конкретного сценария. Затем этот порядок оценки остается на усмотрение компилятора, и у компилятора может быть гарантия.
Важно помнить, что стандарт C ++ - это действительно язык, инструктирующий компилятор по построению ассемблерного / машинного кода. Стандарт - это только часть уравнения. Если стандарт неоднозначен или определен конкретной реализацией, вам следует обратиться к компилятору и понять, как он переводит инструкции C ++ на настоящий машинный язык.
Итак, если порядок оценки является требованием или, по крайней мере, важным, и совместимость с кросс-компилятором не является требованием, исследуйте, как ваш компилятор в конечном итоге объединит это воедино, и ваш ответ может в конечном итоге быть там. Обратите внимание, что компилятор может изменить свою методологию в будущем.
источник