Порядок вычисления параметров функции в C++


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

foo(bar(), baz())

есть ли какая-либо гарантия по стандарту C++, что бар будет оцениваться до baz?

6 73

6 ответов:

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

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

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

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

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

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

порядок вычисления аргументов не уточняется.

из вызова функции [5.2.2],

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

поэтому нет никакой гарантии, что bar() перед baz(), только bar() и baz() перед foo.

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

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

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

C++17 задает порядок вычисления для операторов, который не был определен до C++17. На вопрос каковы гарантии порядка оценки, введенные C++17? но обратите внимание на ваше выражение

foo(bar(), baz())

имеет все еще неопределенный порядок оценки.

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

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

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

Как уже указывали другие, стандарт не дает никаких указаний относительно порядка оценки для данного конкретного сценария. Этот порядок оценки затем оставляется компилятору, и компилятор может иметь гарантию.

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

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