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

Если я напишу f(x)->g(args, ...) могу ли я положиться на точку последовательности после f(x) до оценки args, ...? Я могу видеть аргументы в обоих направлениях:

  • §1.9.17 «При вызове функции (независимо от того, является ли функция встроенной), после вычисления всех аргументов функции (если таковые имеются) существует точка последовательности, которая происходит перед выполнением любых выражений или операторов в теле функции. Существует также точка последовательности после копирования возвращаемого значения и перед выполнением любых выражений вне функции.«
  • С другой стороны, указатель объекта неявно является скрытым аргументом. this как будто я написал g(f(x), args, ...) что говорит о том, что это как аргумент, и, следовательно, не указано.

-> оператор не является нормальным бинарным оператором, так как ясно g(...) не могу оцениваться раньше f(x) как мог бы, если бы я написал f(x) + g(...), Я удивлен, что не могу найти какое-то конкретное заявление по этому поводу.

15

Решение

C ++ 2003 5.2.2 p8

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

Это означает, что есть не последовательность между оценкой f(x) а также args,

В C ++ 2011 вся концепция точек последовательности была заменена (см. N1944), и эта формулировка теперь просто примечание:

[ Замечания: Оценки выражения postfix и выражений аргумента не являются последовательными по отношению друг к другу. Все побочные эффекты при оценке выражений аргументов секвенируются до входа в функцию (см. 1.9). — конечная нота ]

и 1,9 р15 говорит

При вызове функции (независимо от того, является ли функция встроенной), каждое вычисление значения и побочный эффект, связанный с любым выражением аргумента или с выражением постфикса, обозначающим вызываемую функцию, упорядочивается перед выполнением каждого выражения или оператора в теле вызываемая функция. [ Замечания: Вычисления значений и побочные эффекты, связанные с различными выражениями аргументов, не являются последовательными. — конечная нота ]

Это говорит выражение f(x) и выражение args последовательность перед всем в теле g, но они не упорядочены по отношению друг к другу, что соответствует правилам C ++ 03, но сформулировано по-другому.

10

Другие решения

Заметьте, я думаю, что вы задаете один вопрос в заголовке, а другой — в теле вашего вопроса.

Ну, это не совсем противоречиво. Чтобы оценить вашу функцию, должны произойти следующие вещи (не обязательно в этом порядке).

  • х оценивается (А)
  • Аргс оценивается (B)
  • … оценивается (C)
  • f (x) называется (D)
  • возвращаемое значение f (x) копируется (E)
  • return-> g (args, …) называется (F)

Теперь приведенные вами правила показывают, что

  1. (A) должно произойти до (D), так как есть точка последовательности оценки аргументов функции до оценки.
  2. (D) происходит раньше (E), так как копирование не может быть выполнено, пока функция не запустится.
  3. (F) происходит после (E), так как неявный указатель необходим для вызова g (args) *
  4. (B) и (C) происходят раньше (F), так как они являются аргументами.

Однако то, что не упорядочено, это связь между (A), (B) и (C), или в вашем вопросе между (B) и (C) и (D), так как они не являются аргументами для (F), они могут быть оценены впоследствии. ИЛИ, они могут быть оценены ранее.

* Интересный вопрос. Что происходит, если g (args, …) является статической функцией-членом. В этом случае, поскольку возвращенный указатель из f (x) фактически не передается, можно ли упорядочить его раньше? Но это отдельный вопрос.

4

По вопросам рекламы [email protected]