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 ответов

19 просмотров

Видимо, потому что 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 деструктора, но он почему-то один вызывается

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

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

Господа, а что сейчас вообще с рынком труда на делфи происходит? Какова ситуация?
Rꙮman Yankꙮvsky
29
А вообще, что может смущать в самой Julia - бы сказал, что нет единого стандартного подхода по многим моментам, поэтому многое выглядит как "хаки" и произвол. Короче говоря, с...
Viktor G.
2
30500 за редактор? )
Владимир
47
а через ESC-код ?
Alexey Kulakov
29
Гайс, вопрос для разносторонее развитых: читаю стрим с юарта, нада выделять с него фреймы с определенной структурой, если ли чо готовое, или долбаться с ринг буффером? нада у...
Vitaly
9
Чёт не понял, я ж правильной функцией воспользовался чтобы вывести отладочную информацию? но что-то она не ловится
notme
18
У меня есть функция где происходит это: write_bit(buffer, 1); write_bit(buffer, 0); write_bit(buffer, 1); write_bit(buffer, 1); write_bit(buffer, 1); w...
~
14
Добрый день! Скажите пожалуйста, а какие программы вы бы рекомендовали написать для того, чтобы научиться управлять памятью? Можно написать динамический массив, можно связный ...
Филипп
7
Недавно Google Project Zero нашёл багу в SQLite с помощью LLM, о чём достаточно было шумно в определённых интернетах, которые сопровождались рассказами, что скоро всех "ибешни...
Alex Sherbakov
5
длина пакета фиксированная, или меняется?
Okhsunrog
7
Карта сайта