Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.15.219.217] |
|
Страницы: (3) 1 [2] 3 все ( Перейти к последнему сообщению ) |
Сообщ.
#16
,
|
|
|
korvin, в C++ ты почти всегда можешь что-то обойти и испортить себе жизнь. Но зачем?
Добавлено defer(как и with/using/etc.) можно случайно пропустить. RAII же стабилен. |
Сообщ.
#17
,
|
|
|
Цитата korvin @ Да, но такие сложные ресурсы могут запутывать и, опять же, в непредвиденном случае возникновения исключения в деструкторе одного из полей, имеем ту же проблему. Нужно просто не выпускать исключения из деструкторов. Если следовать этому правилу, то непредвиденного не случится, ибо исключения будут ловиться и в деструкторах тех типов, значения которых мы используем в качестве полей. А вообще на практике довольно сложно получить деструктор, бросающий исключения - для этого необходимы дополнительные телодвижения. Проблема то в чём - в двух одновременно "летящих" исключениях. Что будет в Go, если в defer произойдёт паника? У тебя в коде обрабатывается только один результат recover(). |
Сообщ.
#18
,
|
|
|
Мне тут, кстати, подсказали. С noexcept(false) всё работает как надо.
|
Сообщ.
#19
,
|
|
|
А сообщение Игоря об этом ты не видел?
|
Сообщ.
#20
,
|
|
|
Цитата MyNameIsIgor @ Проблема то в чём - в двух одновременно "летящих" исключениях. Что будет в Go, если в defer произойдёт паника? У тебя в коде обрабатывается только один результат recover(). Не читал спеку пока что, но судя по экспериментам, если уже одна паника возникла, то следующая заместит собой предыдущую, т.е. при вызове recover после двух паник, он сможет достать только объект последней паники. См. rec2. Соответственно в данном случае, чтобы поймать обе паники, нужно вызывать recover после каждой. Возможно, размер стэка паник можно настроить, но я в этом сомневаюсь, всё же механизм паник создавался не как аналог механизма исключений в других языках. Добавлено Цитата D_KEY @ А сообщение Игоря об этом ты не видел? Нет. =) Уровень невнимательности 146% |
Сообщ.
#21
,
|
|
|
Цитата korvin @ Да, но такие сложные ресурсы могут запутывать и, опять же, в непредвиденном случае возникновения исключения в деструкторе одного из полей, имеем ту же проблему. Так и деструкторы полей не должны кидать исключения И это, в принципе, нормально. Даже в книжках по яве есть рекомендации, что "функции освобождения" не должны кидать исключения. Дело не в сложности ресурса. Дело в свободе использования любых объектов. Тебе не нужно задумываться, использует ли объект ресурс. Добавлено Цитата korvin @ Возможно, но будет ли это выражение таким же надёжным или опять его можно будет обойти и ввести систему в некорректное состояние? Обойти в C++ можно почти все. ССЗБ. Случайно ты это сделать не сможешь. Добавлено Зато есть желание копипастить один и тот же defer из функции в функцию Добавлено Цитата korvin @ С noexcept(false) всё работает как надо. Скорее работает так, как ты ожидаешь. Надеюсь, ты разобрался, почему? А "как надо" - это не выпускать исключение из деструктора. |
Сообщ.
#22
,
|
|
|
Цитата korvin @ Не удивительно. Пожалуй, следует применять другие методы, нежели копирования поведения. В тематике в частности, ибо он там задалбывает. Цитата D_KEY @ А сообщение Игоря об этом ты не видел? Нет. =) Уровень невнимательности 146% |
Сообщ.
#23
,
|
|
|
Цитата D_KEY @ Даже в книжках по яве есть рекомендации, что "функции освобождения" не должны кидать исключения. Жаль, что этих книжек не читали те, кто проектировал AutoCloseable |
Сообщ.
#24
,
|
|
|
Цитата @@@ @ Жаль, что этих книжек не читали те, кто проектировал AutoCloseable Действительно жаль |
Сообщ.
#25
,
|
|
|
если бы в "функциях освобождения" можно было бы обойтись без выкидывания исключений, то без них можно было обойтись вообще |
Сообщ.
#26
,
|
|
|
Цитата wind @ если бы в "функциях освобождения" можно было бы обойтись без выкидывания исключений, то без них можно было обойтись вообще Без исключений? Во-первых, без них действительно можно обойтись. Во-вторых, если "функциям освобождения" не кидают исключения, то это существенно упрощает построение безопасного в плане исключений кода. В-третьих, каким образом из вашей посылки следует ваш вывод? В С++, например, деструкторы исключений не кидают, при этом исключения могут активно использоваться. |
Сообщ.
#27
,
|
|
|
Цитата D_KEY @ Не упрощают, а делает возможным. И "в плане исключений" лишнее. Любые состояния ошибок в любых функциях очистки делают код абсолютно ничего не гарантирующим. Во-вторых, если "функциям освобождения" не кидают исключения, то это существенно упрощает построение безопасного в плане исключений кода. |
Сообщ.
#28
,
|
|
|
Цитата Qraizer @ Не упрощают, а делает возможным. В C++. В Java исключение в "функции освобождения" ничего не сломает и не приведет к потери информации. Цитата Любые состояния ошибок в любых функциях очистки делают код абсолютно ничего не гарантирующим. Тем не менее, в функциях очистки ошибки могут происходить. Например потому, что API ОС, как правило, предполагает коды ошибок для функций закрытия. В C++ в деструкторе ты можешь(после логирования) либо проигнорировать либо упасть. Добавлено Цитата D_KEY @ В Java исключение в "функции освобождения" ничего не сломает и не приведет к потери информации Поясню: import java.lang.*; class A implements AutoCloseable { public void close() { throw new RuntimeException("CloseError"); } } class Ideone { public static void main (String[] args) throws java.lang.Exception { try(A a = new A()) { throw new RuntimeException("MainError"); } } } Exception in thread "main" java.lang.RuntimeException: MainError at Ideone.main(Main.java:22) Suppressed: java.lang.RuntimeException: CloseError at A.close(Main.java:11) at Ideone.main(Main.java:23) http://ideone.com/WRjcGH#stderr Естественно, мы сможем сами так же отловить и пройтись по списку подавленных исключений. |
Сообщ.
#29
,
|
|
|
Цитата D_KEY @ Естественно. Но любая такая хрень означает, что ошибка в программе. Например, почему CloseHandle() может упасть? Разве что из-за испорченнего HANDLE, который потёр кривой поинтер. Или потому, что тот уже закрыт. Когда все подобные ошибки будут исправлены, функции очистки тоже будут успешны.Тем не менее, в функциях очистки ошибки могут происходить. Например потому, что API ОС, как правило, предполагает коды ошибок для функций закрытия. Речь о том, что в безошибочной программе функции очистки никогда не столкнутся с такими ситуациями. Поэтому разрабатывать их с учётом подобных ситуаций нет необходимости. Если же такая необходимость возникла, то это значит лишь то, что программа плохо спроектирована, и некоторые действия в ней не должны размещаться в функциях очистки, т.к. не связаны с освобождением ресурсов. Помнишь, например, дискуссию о FreeAndNIL() в контексте Clear(), вызываемой в деструкторе? Там сами дельфисты нагородили костылей и пытались показать, что это нормально. |
Сообщ.
#30
,
|
|
|
Цитата Qraizer @ Естественно. Но любая такая хрень означает, что ошибка в программе. Проблема в том, что языки, в основном, предоставляют возможность "подавления" таких ошибок, т.к. ошибка может быть в сторонней либе, которую приходится использовать независимо от её кривости (например, если воркэроунд быстрее, проще и дешевле, чем повторная реализация нужного функционала без косяков). В итоге получаем, что ассерты и паники можно таки отловить, нивелируя их цель --- гарантированное падение программы и сигнализация о баге. |