При вызове функции C / C ++ в другой функции, зачем они складываются? Есть ли способ исправить это? [Дубликат]

Я бы сказал, что это pass-by-copy -

. Рассмотрение аргументов и объектов переменных - это объекты, созданные во время контекста выполнения, созданного в начале вызова функции, - и ваше фактическое значение / ссылка, переданная в функция просто хранится в этих аргументах + объекты переменных.

Проще говоря, для примитивных типов значения копируются в начале вызова функции, для типа объекта ссылка копируется.

71
задан Clark Gaebel 29 May 2010 в 12:55
поделиться

6 ответов

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

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

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

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

int x = f(2) + g(3);   // undefined whether f() or g() is called first
85
ответ дан Matteo Italia 22 August 2018 в 16:05
поделиться
  • 1
    Я могу принять этот ответ за 8 минут ... Наверное, я немного зацикливаюсь! – Clark Gaebel 29 May 2010 в 13:02
  • 2
    Да, но лучший код может быть WRITTEN (= cleaner), если порядок оценки выражения был STRICT, что, как правило, намного важнее, чем генерация кода. См. Этот пример: stackoverflow.com/questions/43612592/… Итак, Stroustrup. – Bill Kotsias 25 April 2017 в 13:57
  • 3
    Если вы заказываете вопросы, вы можете сами выполнять последовательность. В противном случае всегда будет стоить что-то, что не всегда (редко?) Имеет значение. Я думаю, что политика не платить за то, что вы не используете, - это единственное, на что согласны большинство программистов на С ++. – tweej 2 December 2017 в 10:53
  • 4
    Не должно быть «неопределенного поведения». вместо "undefined"? – GoodDeeds 6 January 2018 в 20:38
  • 5
    @GoodDeeds Prior C ++ 17, неопределенное поведение, если функции вызывают побочные эффекты в том же месте памяти. Post C ++ 17 не указывается. – Passer By 22 June 2018 в 16:53

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

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

Поэтому нет гарантии, что bar() будет работать до baz(), только bar() и baz() будет вызываться до foo.

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

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

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

14
ответ дан Daniel Trebbien 22 August 2018 в 16:05
поделиться
  • 1
    Пример "специального примечания" из [5.14] Логический оператор И: «В отличие от &, && гарантирует оценку слева направо: второй операнд не оценивается, если первый операнд false. – Daniel Trebbien 29 May 2010 в 13:31

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

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

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

0
ответ дан Erudite Programmer 22 August 2018 в 16:05
поделиться

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

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

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

2
ответ дан R Sahu 22 August 2018 в 16:05
поделиться

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

foo(bar(), baz())

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

7
ответ дан S.M. 22 August 2018 в 16:05
поделиться

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

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

20
ответ дан user 22 August 2018 в 16:05
поделиться
  • 1
    Тот факт, что они оцениваются до foo (), по крайней мере, немного успокаивает. – Bill Kotsias 25 April 2017 в 13:58
Другие вопросы по тегам:

Похожие вопросы: