170 похожих чатов

Почему не вызывается деструктор для возвращаемого объекта S{3} в foo()? в

стандарте написано "If an exception is thrown during the destruction of temporaries or local variables for a return statement ([stmt.return]), the destructor for the returned object (if any) is also invoked"

https://godbolt.org/z/9E587deEf
https://eel.is/c++draft/except.ctor#2

43 ответов

11 просмотров

Видимо, потому что RVO... ( код даже не смотрел)

Максим-Б Автор вопроса

Ну и вызываются только деструкторы тех объектов, которые был СКОНСТРУИРОВАНЫ, причём, полностью.

Максим-Б Автор вопроса
Sergey Sobolev
return S{3}; // а не {3}

развернёте ответ? пока не очень понял

Максим Б
rvo отключено через -fno-elide-constructors

там где оно отключено всё четко вызывается

Максим-Б Автор вопроса
Андрей Руссков
там где оно отключено всё четко вызывается

T S(3) ~T catch S(4) S(S& = 4) ~S(4) -- ~S(4) у меня такой вывод с отключённым рво, а у вас?

Максим-Б Автор вопроса
Sergey Sobolev
https://godbolt.org/z/hn3Ec58YK

ага а можете, пож, объяснить, почему так?

Максим-Б Автор вопроса
Ilya Zviagin
Ну и вызываются только деструкторы тех объектов, к...

а как может позваться деструктор локального объекта во время конструирования возвращаемого? (вывод в консоль из констуктора возвращаемого произошёл)

Ilya Zviagin
Ну и вызываются только деструкторы тех объектов, к...

возвращаемый объект сконструирован к моменту вызова деструкторов локальных объектов

Так у тебя там вообще, исключение в деструкторе...

Максим-Б Автор вопроса
Ilya Zviagin
Так у тебя там вообще, исключение в деструкторе...

стандартом это не запрещено, если я правильно понял

Максим-Б Автор вопроса

этот пример, если что - повторение Note из стандарта

Максим Б
стандартом это не запрещено, если я правильно поня...

Ну да, но terminate вызывать будет. https://en.cppreference.com/w/cpp/error/terminate А терминате - аборт. https://en.cppreference.com/w/cpp/utility/program/abort А он деструкторы не зовёт

Максим-Б Автор вопроса
Ilya Zviagin
Ну да, но terminate вызывать будет. https://en.c...

terminate вызвать не будет, деструктор определён как noexcept(false)

Максим-Б Автор вопроса
Ilya Zviagin
Ну и ?

terminate не вызывается -> abort не вызывается -> выполнение продолжается -> должен позваться деструктор возвращаемого объекта, но не зовётся

Ilya Zviagin
Ну и ?

Бросать исключения из деструктора можно, если пометить его noexcept(false)

Alexander Karaev
Нет.

Правильно, если его не поймаешь...

Максим-Б Автор вопроса
Ilya Zviagin
И если его бросаешь, вызывается terminate

вот про терминейт "Whenever an exception is thrown and the search for a handler ([except.handle]) encounters the outermost block of a function with a non-throwing exception specification" https://eel.is/c++draft/except.spec#5

gcc, смотрю, ведет себя точно так же msvc пробовали?

Максим-Б Автор вопроса
Vlad
gcc, смотрю, ведет себя точно так же msvc пробовал...

msvc под рукой нет, а годболт его пока не умеет запускать)

Максим Б
T S(3) ~T catch S(4) S(S& = 4) ~S(4) -- ~S(4) у м...

У вас в правой вкладке, где вы компилируете с 17 стандартом рво не отключен и работает. Другое дело что такой сайд-эффект от рво выглядит как баг.

Максим-Б Автор вопроса
Aleksei Kuznetsov Kuznetsov
У вас в правой вкладке, где вы компилируете с 17 с...

да, правая вкладка была сначала, потом я левую сделал с отключением рво, пардон за неоднозначность

Максим-Б Автор вопроса
Vlad
19.30.30423 (vs 2022 preview 3) T S(3) ~T catch S(...

хм! я, правда, очень сомневаюсь, что баг сразу в трёх главных компиляторах, скорее это я чё-то проморгал, но вот пока не могу понять, что)

Максим Б
да, правая вкладка была сначала, потом я левую сде...

Да, я глянул оригинальный годболт и понял, сорян. return {3} это initilizer_list видимо по какойто причине это ломает лайфтайм возвращаемому объекту и не генерит вызов деструктора. Но выглядит как баг честно говоря, мне не приходит в голову что в стандарте это нарушает. Если явно сконструировать тип return S{3} и вырубить rvo то все выглядит корректно, но рво один хрен не должно менять поведение.

Можно и моё любопытство удовлетворить? Зачем ты бросаешь исключение в деструкторе?

Максим Б
хм! я, правда, очень сомневаюсь, что баг сразу в т...

однако пока что ничто не опровергает тот пункт, который вы привели в самом начале

Ilya Zviagin
Можно и моё любопытство удовлетворить? Зачем ты б...

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

Максим-Б Автор вопроса
Ilya Zviagin
Можно и моё любопытство удовлетворить? Зачем ты б...

конечно! я набрёл на этот пример в стандарте. там искл бросается, потому что это пример, иллюстрирующий пункт "шо там с деструкциями при исключении в деструкторе")

Максим-Б Автор вопроса
Ilya Zviagin
Ну ок, я просто спросил...

ноль проблем, ответил)

Максим Б
спасибо за поддержку!

Да, еслиб не он, я б тебя уже съел...

Aleksei Kuznetsov Kuznetsov
Да, я глянул оригинальный годболт и понял, сорян. ...

Во всех вариациях теряется один вызов деструктора. В том числе при явном конструировании объекта S{3}: после него происходит копирование и деструктор вызывается лишь на одном объекте.

Максим Б
хм! я, правда, очень сомневаюсь, что баг сразу в т...

я не знаю, как можно обойти такую четкую формулировку, еще и с примером http://eel.is/c++draft/except.ctor#2.sentence-2 а то, что основные имплементации отлично умеют ошибаться, мы уже проходили с constant evaluation. по-моему, все вместе в том числе

magras
Во всех вариациях теряется один вызов деструктора....

Да, точно. Проглядел конструктор копирования.

в общем, это действительно баги в компиляторах, причем старые. пишут, что в gcc исправили, но пример из стандарта по-прежнему работает неправильно https://bugs.llvm.org/show_bug.cgi?id=13505 https://bugs.llvm.org/show_bug.cgi?id=12286 https://bugs.llvm.org/show_bug.cgi?id=12286#c4 это я вычитал здесь, а потом нашел в багтрекере: Clause 18.2.2. requires local temporaries, such as return values, to have their destructors called when unwinding. However, clang’s existing exception implementation does not conform to this part of the specification

Sergey Sobolev
return S{3}; // а не {3}

тоже не поможет, вызовется конструктор копии и у нас будет уже 2 объекта, и соответственно должно быть 2 деструктора, но он почему-то один вызывается

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

Обсуждают сегодня

Какой-то там пердун в 90-х решил, что есть какая-то разная типизация. Кого вообще это волнует?
КТ315
49
void terminal_scroll() { memmove(terminal_buffer, terminal_buffer + VGA_WIDTH, buffer_size - VGA_WIDTH); memset(terminal_buffer + buffer_size - VGA_WIDTH, 0, VGA_WIDTH); ...
Егор
47
Всем привет! Подскажите, пожалуйста, в чем ошибка? Настраиваю подключение к MySQL. Либы лежат рядом с exe. Все как по "учебнику"
Евгений
16
А можете как-то проверить меня по знаниям по ассемблеру?
A A
132
Здравствуйте! У меня появилась возможность купить книгу "Изучай Haskell во имя добра!". Но я где-то слышал, что эта книга устарела. Насколько это правда??
E
22
Здравствуйте! Я вот на stepic решаю задачи на хаскеле https://stepik.org/lesson/8443/step/8?unit=1578 мой код import Data.List (isInfixOf) removing :: String -> [String] ->...
E
10
Камрады, кто тесно работал с vtv, хотел уточнить. Ширина column задаётся жёстко на этапе создания дерева или можно в рантайме ее менять программно (не мышкой)?
Ed Doc
10
да ладно ... что там неочевидного ? глянуть в исх-ки датасета и/или кверика чтобы понять в каком месте и как выполняется обращения к св-вам blablaSQL - минутное дело, даже е...
Сергей
7
Здесь для arm кто-нибудь кодит ?
Nothing
52
Всем привет, у меня есть сервер принимающий входящие HTTP подключения, как проверить, что подключение было через прокси или нет, есть какие то поля в заголовках по которым мо...
DS
8
Карта сайта