Порядок вычисления в параметрах функции C ++ - PullRequest
78 голосов
/ 29 мая 2010

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

foo(bar(), baz())

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

Ответы [ 6 ]

89 голосов
/ 29 мая 2010

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

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

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

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

int x = f(2) + g(3);   // undefined whether f() or g() is called first
20 голосов
/ 29 мая 2010

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

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

17 голосов
/ 29 мая 2010

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

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

Следовательно, нет гарантии, что bar() будет запущен до baz(), только что bar() и baz() будут вызваны до foo.

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

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

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

9 голосов
/ 03 декабря 2017

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

foo(bar(), baz())

имеет еще неуказанный порядок оценки.

2 голосов
/ 02 декабря 2017

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

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

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

0 голосов
/ 09 декабря 2017

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

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

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

...