Это переменные для адресов в выходных данных:
0x7ffc4445737a a
0x7ffc4445735f x
0x7ffc4445737c return value of f()
0x7ffc4445737b b
0x7ffc4445737e y
0x7ffc4445737f return value of g()
0x7ffc4445737d c
Я интерпретирую вопрос как: вы выделяете следующие две точки:
x
is уничтожено до того, как b
построено y
уничтожено после того, как c
построено
и спросите, почему оба случая не ведут себя одинаково.
Ответ таков: в C ++ 14 стандарт, указанный в [expr.call] / 4, что y
должен быть уничтожен при возврате функции. Однако не было четко указано, на каком этапе возврата функции это означает. Возникла проблема с CWG.
Начиная с C ++ 17, спецификация теперь такова, что она определяется реализацией, уничтожается ли y
одновременно с локальными переменными функции или в конце полное выражение, содержащее вызов функции. Оказалось, что два случая не могут быть согласованы, потому что это будет серьезное изменение ABI (подумайте, что произойдет, если деструктор y
сгенерирует исключение); а также Itanium C ++ ABI определяет разрушение в конце полного выражения.
Мы не можем однозначно сказать, что g++ -std=c++14
не соответствует C ++ 14 из-за неоднозначности C + +14 формулировка, однако в любом случае она не изменится сейчас из-за проблемы ABI.
Для объяснения со ссылками на Стандарт и отчет CWG см. Этот вопрос: Последовательность функций уничтожение параметров , а также Позднее уничтожение параметров функции