Существует ли точка последовательности между вызовом функции, возвращающей объект, и вызовом метода для этого объекта?
Если я напишу f(x)->g(args, ...)
могу ли я положиться на точку последовательности после f(x)
до оценки args, ...
? Я могу видеть аргументы в обоих направлениях:
- §1.9.17 "При вызове функции (независимо от того, является ли функция встроенной), после вычисления всех аргументов функции (если таковые имеются) существует точка последовательности, которая происходит перед выполнением любых выражений или операторов в теле функции. Существует также точка последовательности после копирования возвращенного значения и перед выполнением любых выражений вне функции."
- С другой стороны, указатель объекта неявно является скрытым аргументом.
this
как будто я написалg(f(x), args, ...)
что говорит о том, что это как аргумент, и, следовательно, не указано.
->
оператор не является нормальным бинарным оператором, так как g(...)
нельзя оценить раньше f(x)
как мог бы, если бы я написал f(x) + g(...)
, Я удивлен, что не могу найти какое-то конкретное заявление по этому поводу.
2 ответа
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, но сформулировано по-другому.
Заметьте, я думаю, что вы задаете один вопрос в своем названии, а другой - в теле вашего вопроса.
Ну, это не совсем противоречиво. Чтобы оценить вашу функцию, должны произойти следующие вещи (не обязательно в этом порядке).
- х оценивается (А)
- Аргс оценивается (B)
- ... оценивается (C)
- f(x) называется (D)
- возвращаемое значение f(x) копируется (E)
- return-> g (args,...) называется (F)
Теперь приведенные вами правила показывают, что
- (A) должно произойти до (D), так как есть точка последовательности оценки аргументов функции до оценки.
- (D) происходит раньше (E), поскольку копирование не может быть выполнено, пока функция не запустится.
- (F) происходит после (E), так как неявный указатель необходим для вызова g (args) *
- (B) и (C) происходят раньше (F), так как они являются аргументами.
Однако то, что не упорядочено, это связь между (A), (B) и (C), или в вашем вопросе между (B) и (C) и (D), так как они не являются аргументами для (F), они могут быть оценены впоследствии. ИЛИ, они могут быть оценены ранее.
* Интересный вопрос. Что происходит, если g (args,...) является статической функцией-членом. В этом случае, поскольку возвращенный указатель из f(x) фактически не передается, можно ли упорядочить его раньше? Но это отдельный вопрос.