Если у нас есть три функции (foo, bar и baz), которые составлены так ...
foo(bar(), baz())
Есть ли гарантия по стандарту C ++, что bar будет оценен до baz?
Если у нас есть три функции (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
, затем строку 1 baz
, затем строку 2 bar
и т. Д.), Что тоже хорошо. :-)
C ++ 17 определяет порядок оценки для операторов, который не был указан до C ++ 17. См. Вопрос Каковы гарантии порядка оценки, введенные в C ++ 17? Но обратите внимание на ваше выражение
foo(bar(), baz())
еще не определен порядок оценки.
В C ++ 11 соответствующий текст можно найти в 8.3.6 Аргументы по умолчанию / 9 (выделено мной)
Аргументы по умолчанию оцениваются каждый раз при вызове функции. Порядок оценки аргументов функции не указан . Следовательно, параметры функции не должны использоваться в аргументе по умолчанию, даже если они не оцениваются.
Такое же словоблудие используется и в стандарте C ++ 14, и его можно найти в том же разделе .
Как уже отмечали другие, стандарт не дает никаких указаний по порядку оценки для этого конкретного сценария. Затем этот порядок оценки остается на усмотрение компилятора, и у компилятора может быть гарантия.
Важно помнить, что стандарт C ++ - это действительно язык, инструктирующий компилятор по построению ассемблерного / машинного кода. Стандарт - это только часть уравнения. Если стандарт неоднозначен или определен конкретной реализацией, вам следует обратиться к компилятору и понять, как он переводит инструкции C ++ на настоящий машинный язык.
Итак, если порядок оценки является требованием или, по крайней мере, важным, и совместимость с кросс-компилятором не является требованием, исследуйте, как ваш компилятор в конечном итоге объединит это воедино, и ваш ответ может в конечном итоге быть там. Обратите внимание, что компилятор может изменить свою методологию в будущем.