Re[2]: Что делать с проблемами в деструкторе?
От: _NN_ www.nemerleweb.com
Дата: 18.11.15 21:33
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Экспериментальная альтернатива — двухфазная семантика разрушения. Вместо деструктора пишутся два метода release и deferred — release выполняется всегда в самом конце, deferred выполняется перед release и только в случае если не летит исключение. В итоге пример выше переписывается в:

EP>
EP>{
EP>   File a,b;
EP>   // ... - may throw   
EP>}
EP>


EP>Обсуждение
Автор: Evgeny.Panasyuk
Дата: 27.09.12
по теме.

Стандартизировать это еще не собираются в C++17
Там какой-нибудь синтаксис в стиле
class File 
{
public:
 ~File()
 {
  // старый добрый деструктор без исключений
 }

 ~~File()
 {
  // а тут можно кинуть если надо
 }
}
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[3]: Что делать с проблемами в деструкторе?
От: Evgeny.Panasyuk Россия  
Дата: 18.11.15 21:48
Оценка:
Здравствуйте, _NN_, Вы писали:

EP>>Обсуждение
Автор: Evgeny.Panasyuk
Дата: 27.09.12
по теме.

_NN>Стандартизировать это еще не собираются в C++17

std::uncaught_exceptions уже в текущем Draft'е — 18.8.4.
Но для кидающих деструкторов его всё же следует использовать с осторожностью. Дело в том что объект созданный в одном scope может переехать в другой — в котором будет другое начальное значение uncaught_exceptions.
Для реализаций scope(failure) и scope(success) — это не проблема, так как их объекты-guard'ы живут в одном scope.
Re[5]: Что делать с проблемами в деструкторе?
От: CEMb  
Дата: 19.11.15 06:22
Оценка:
Здравствуйте, Vlad_SP, Вы писали:

CEM>> К примеру, файл полностью записан и закрыт.


V_S>В файл записалась только половина данных, дальше кончилось место на диске.

V_S>На сервер в Тимбукту передана только половина данных, дальше пьяный экскаваторщик Вася в Мухосранске порвал магистральный кабель.
V_S>И так далее....

Ну и нормально. Файл полностью записать и закрыт? Нет — объект отправляем в пул. Не вижу проблем.
Re[6]: Что делать с проблемами в деструкторе?
От: CEMb  
Дата: 19.11.15 06:25
Оценка:
Здравствуйте, landerhigh, Вы писали:

L>Всем такие события поздновато разруливать в деструкторе.

L>В принципе можно, но под этим деструктором должна быть еще куча уровней, которые умеют это разруливать сами.

Ну вот я для того пункт 2 и придумал, чтобы это был и деструктор и не наш, т.е. у нашего объекта ещё было время сделать корректно все свои дела перед своим деструктором. Вообще мне такая схема кажется кривой и избыточной, но больше пока ничего не придумал.
Re[4]: Что делать с проблемами в деструкторе?
От: _NN_ www.nemerleweb.com
Дата: 19.11.15 07:20
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Здравствуйте, _NN_, Вы писали:


EP>>>Обсуждение
Автор: Evgeny.Panasyuk
Дата: 27.09.12
по теме.

_NN>>Стандартизировать это еще не собираются в C++17

EP>std::uncaught_exceptions уже в текущем Draft'е — 18.8.4.

Это в курсе.
Я про человечный синтаксис для TWO_STAGE_DESTRUCTOR_DEFERRED, TWO_STAGE_DESTRUCTOR_RELEASE.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[7]: Что делать с проблемами в деструкторе?
От: landerhigh Пират  
Дата: 19.11.15 15:50
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Альтернативный вариант, озвученный в статье, это игнорировать все кроме первого исключения.


Ну это просто праздник какой-то!

EP>Думаю можно вызывать глобальный пользовательский callback для игнорируемых исключений.


Так его и так никто не мешает сделать прямо сейчас

L>>Но у меня другой вопрос — а что с объектом-то? Вот выкинул он исключение на полпути деструктора. И стал зомби. Вернуть к жизни его нельзя. Добить? Как? Разрешать рекуррентный вызов деструктора, чтобы наверняка добить? Так это ничем не отличается от цепочки cleanup() — delete.

L>>Или принять ограничения, что исключение в деструкторе — чисто информационное и объект, выбросивший его, гаратированно убит?
EP>Например в само исключение можно запаковывать все внутренности объекта. То есть например file handle будет внутри объекта исключения.

Это же нарушает инкапсуляцию. Да и вся сила RAII в том, что клиенты не обязаны знать, что под капотом объекта там что-то такое происходит. А тут — красиво заворачиваем кишочки объекта в праздничную упаковку и перебрасываем ее через забор, авось кто поймает
www.blinnov.com
Re[2]: Что делать с проблемами в деструкторе?
От: wander  
Дата: 19.11.15 17:23
Оценка:
Здравствуйте, T4r4sB, Вы писали:

TB>В деструкторе записывать успешность результата во внешнюю переменную (ссылка на которую даётся в конструкторе). Потом проверять эту переменную.


Можно даже пойти дальше и сделать ленивый проброс исключений.
class A
{
//.....
    ~A() {
         if(!m_file.save())
             LASY_THROW(FileSaveException());
     }
};

///...........
{
    A a;
    // do some stuff
    // ....
}
RETHROW();

Но это, конечно, тоже полумера и не всегда уместная.
Re[8]: Что делать с проблемами в деструкторе?
От: Evgeny.Panasyuk Россия  
Дата: 19.11.15 17:28
Оценка:
Здравствуйте, landerhigh, Вы писали:

EP>>Альтернативный вариант, озвученный в статье, это игнорировать все кроме первого исключения.

L>Ну это просто праздник какой-то!

Всяко лучше чем std::terminate.

EP>>Думаю можно вызывать глобальный пользовательский callback для игнорируемых исключений.

L>Так его и так никто не мешает сделать прямо сейчас

Сейчас игнорируются (программистами) все исключения в деструкторах, и нет общего надёжного способа узнать когда можно кидать исключение, а когда будет std::terminate.
В этом же варианте по сути вместо std::terminate будет вызван пользовательский callback.

L>>>Но у меня другой вопрос — а что с объектом-то? Вот выкинул он исключение на полпути деструктора. И стал зомби. Вернуть к жизни его нельзя. Добить? Как? Разрешать рекуррентный вызов деструктора, чтобы наверняка добить? Так это ничем не отличается от цепочки cleanup() — delete.

L>>>Или принять ограничения, что исключение в деструкторе — чисто информационное и объект, выбросивший его, гаратированно убит?
EP>>Например в само исключение можно запаковывать все внутренности объекта. То есть например file handle будет внутри объекта исключения.
L>Это же нарушает инкапсуляцию. Да и вся сила RAII в том, что клиенты не обязаны знать, что под капотом объекта там что-то такое происходит. А тут — красиво заворачиваем кишочки объекта в праздничную упаковку и перебрасываем ее через забор, авось кто поймает

Я описывал чисто технические внутренности, в реальности этот кидаемый file handle может быть завёрнут в полноценную RAII обёртку, которая автоматически закроет файл даже если наверху это исключение не обработается специальным образом (например будут ловить только базовое std::exception).
То есть мой поинт не в том что нужно кидаться голыми кишками, а в том что нет проблемы в том что мы находимся в деструкторе объекта File, и после выброса исключения он прекратит своё существование. Мы можем запоковать всё необходимое во внутрь исключения, тем самым продлив время жизни необходимых ресурсов на время раскрутки стэка — а уже наверху смогут принять конкретные решения.
Re: Что делать с проблемами в деструкторе?
От: mavrii  
Дата: 20.11.15 00:05
Оценка:
Я не использую исключения, а использую параметр ошибки.

CFile {
Error &m_ErrorCode;

CFile( param, Error &err ):
m_ErrorCode(err),... {
}

~CFile() {
// use m_ErrorCode
}
};

Error& soSometing( some params, Error &err ) {
CFile file("myfile", err );
return err;
}

Объект Error это reference который идет по стэку и обьявлен исходя из логики программы.
Re[9]: Что делать с проблемами в деструкторе?
От: landerhigh Пират  
Дата: 20.11.15 00:28
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

L>>Ну это просто праздник какой-то!


EP>Всяко лучше чем std::terminate.


Чем же лучше? Что вобще может выдать ошибку в деструкторе? "Не могу вернуть память"? Бугага. "Ниасилил записать"? По логике, если это происходит в деструкторе, то обычно это значит, что "ну и чорд с ним". А вот если вовсе не "чорд с ним", то terminate — наше фсио!
Я, конечно, знаю примеры, когда деструктор вызывал такую длинную цепочку вызовов, что из нее могло прилететь все, что угодно. Но это вовсе не значит, что нужно так делать. И то, что это спрятано внутри вызова деструктора, как бы намекает, что код, использующий этот класс, вовсе не обязан быть в курсе всей происходящей за кулисами кухни.

EP>Сейчас игнорируются (программистами) все исключения в деструкторах, и нет общего надёжного способа узнать когда можно кидать исключение, а когда будет std::terminate.


В принципе, в каждом таком треде все это сводится к одному-единственному примеру. "Класс закрывает файл в деструкторе, а вдруг закрытие файла обломается". Я же считаю, что это сферическое программирование в вакууме. Если при закрытии файла выскочила ошибка, то что-то сделать, чтобы исправить эту конкретную ошибку, пользовательский код уже вряд ли сможет.

EP>В этом же варианте по сути вместо std::terminate будет вызван пользовательский callback.


L>>>>Но у меня другой вопрос — а что с объектом-то? Вот выкинул он исключение на полпути деструктора. И стал зомби. Вернуть к жизни его нельзя. Добить? Как? Разрешать рекуррентный вызов деструктора, чтобы наверняка добить? Так это ничем не отличается от цепочки cleanup() — delete.

L>>>>Или принять ограничения, что исключение в деструкторе — чисто информационное и объект, выбросивший его, гаратированно убит?
EP>>>Например в само исключение можно запаковывать все внутренности объекта. То есть например file handle будет внутри объекта исключения.

Не-не-не, что с оригинальным объектом? Вот на полпути в деструкторе вылетает исключение. Оно делает невозможным как продолжение выполнения кода деструктора, так и собственно освобождение остальных ресурсов объекта. То есть логика завершения работы объекта идет побоку, а там может быть чего понавороченнее, чем просто "закрыть файл".

EP>То есть мой поинт не в том что нужно кидаться голыми кишками, а в том что нет проблемы в том что мы находимся в деструкторе объекта File, и после выброса исключения он прекратит своё существование. Мы можем запоковать всё необходимое во внутрь исключения, тем самым продлив время жизни необходимых ресурсов на время раскрутки стэка — а уже наверху смогут принять конкретные решения.


Что-то франкенштейн какой-то получается, честное слово. Одна нога тут, другая там, а голова вообще в Филадельфии
www.blinnov.com
Re[2]: Что делать с проблемами в деструкторе?
От: jahr  
Дата: 25.11.15 09:59
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:


EP>Альтернатива — scope(success):


Как раз появилась статья на хабре на эту тему — http://habrahabr.ru/post/270545/, как я понимаю написана по мотивам рассуждений Александреску на эту тему, решил здесь оставить ссылку на случай если кто-то еще будет чимтать этот тред когда-то потом.)
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.