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