На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! Правила раздела:
1. Название темы - краткое описание кто/что против кого/чего
2. В первом сообщении - список параметров, по которым идет сравнение.
3. Старайтесь аргументировать свои высказывания. Фразы типа "Венда/Слюникс - ацтой" считаются флудом.
4. Давайте жить дружно и не доводить обсуждение до маразма и личных оскорблений.
Модераторы: Модераторы, Комодераторы
Страницы: (3) 1 [2] 3  все  ( Перейти к последнему сообщению )  
> C++ RAII/exceptions vs Golang defer/panic/recover
    korvin, в C++ ты почти всегда можешь что-то обойти и испортить себе жизнь. Но зачем?

    Добавлено
    defer(как и with/using/etc.) можно случайно пропустить. RAII же стабилен.
      Цитата korvin @
      Да, но такие сложные ресурсы могут запутывать и, опять же, в непредвиденном случае возникновения исключения в деструкторе одного из полей, имеем ту же проблему.

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

      Проблема то в чём - в двух одновременно "летящих" исключениях. Что будет в Go, если в defer произойдёт паника? У тебя в коде обрабатывается только один результат recover().
        Мне тут, кстати, подсказали. С noexcept(false) всё работает как надо.
          А сообщение Игоря об этом ты не видел?
            Цитата MyNameIsIgor @
            Проблема то в чём - в двух одновременно "летящих" исключениях. Что будет в Go, если в defer произойдёт паника? У тебя в коде обрабатывается только один результат recover().

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

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

            Добавлено
            Цитата D_KEY @
            А сообщение Игоря об этом ты не видел?

            Нет. =) Уровень невнимательности 146%
            Сообщение отредактировано: korvin -
              Цитата korvin @
              Да, но такие сложные ресурсы могут запутывать и, опять же, в непредвиденном случае возникновения исключения в деструкторе одного из полей, имеем ту же проблему.

              Так и деструкторы полей не должны кидать исключения :) И это, в принципе, нормально. Даже в книжках по яве есть рекомендации, что "функции освобождения" не должны кидать исключения.

              Дело не в сложности ресурса. Дело в свободе использования любых объектов. Тебе не нужно задумываться, использует ли объект ресурс.

              Добавлено
              Цитата korvin @
              Цитата D_KEY @
              Далее, defer выразим через RAII посредством guard'ов.

              Возможно, но будет ли это выражение таким же надёжным или опять его можно будет обойти и ввести систему в некорректное состояние?

              Обойти в C++ можно почти все. ССЗБ. Случайно ты это сделать не сможешь.

              Добавлено
              Цитата korvin @
              Цитата D_KEY @
              RAII через defer не сделать.

              Да как-то и желания нет.

              Зато есть желание копипастить один и тот же defer из функции в функцию :D

              Добавлено
              Цитата korvin @
              С noexcept(false) всё работает как надо.

              Скорее работает так, как ты ожидаешь. Надеюсь, ты разобрался, почему?

              А "как надо" - это не выпускать исключение из деструктора.
                Цитата korvin @
                Цитата D_KEY @
                А сообщение Игоря об этом ты не видел?

                Нет. =) Уровень невнимательности 146%
                Не удивительно. Пожалуй, следует применять другие методы, нежели копирования поведения. В тематике в частности, ибо он там задалбывает.
                  Цитата D_KEY @
                  Даже в книжках по яве есть рекомендации, что "функции освобождения" не должны кидать исключения.

                  Жаль, что этих книжек не читали те, кто проектировал AutoCloseable :D
                    Цитата @@@ @
                    Жаль, что этих книжек не читали те, кто проектировал AutoCloseable :D

                    Действительно жаль :'(
                      Цитата @@@ @
                      Жаль, что этих книжек не читали те, кто проектировал AutoCloseable :D

                      если бы в "функциях освобождения" можно было бы обойтись без выкидывания исключений, то без них можно было обойтись вообще
                        Цитата wind @
                        Цитата @@@ @
                        Жаль, что этих книжек не читали те, кто проектировал AutoCloseable :D

                        если бы в "функциях освобождения" можно было бы обойтись без выкидывания исключений, то без них можно было обойтись вообще

                        Без исключений? Во-первых, без них действительно можно обойтись. Во-вторых, если "функциям освобождения" не кидают исключения, то это существенно упрощает построение безопасного в плане исключений кода. В-третьих, каким образом из вашей посылки следует ваш вывод? В С++, например, деструкторы исключений не кидают, при этом исключения могут активно использоваться.
                          Цитата D_KEY @
                          Во-вторых, если "функциям освобождения" не кидают исключения, то это существенно упрощает построение безопасного в плане исключений кода.
                          Не упрощают, а делает возможным. И "в плане исключений" лишнее. Любые состояния ошибок в любых функциях очистки делают код абсолютно ничего не гарантирующим.
                            Цитата Qraizer @
                            Не упрощают, а делает возможным.

                            В C++. В Java исключение в "функции освобождения" ничего не сломает и не приведет к потери информации.

                            Цитата
                            Любые состояния ошибок в любых функциях очистки делают код абсолютно ничего не гарантирующим.

                            Тем не менее, в функциях очистки ошибки могут происходить. Например потому, что API ОС, как правило, предполагает коды ошибок для функций закрытия. В C++ в деструкторе ты можешь(после логирования) либо проигнорировать либо упасть.

                            Добавлено
                            Цитата D_KEY @
                            В Java исключение в "функции освобождения" ничего не сломает и не приведет к потери информации

                            Поясню:

                            ExpandedWrap disabled
                              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");
                                      }
                                  }
                              }

                            ExpandedWrap disabled
                              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

                            Естественно, мы сможем сами так же отловить и пройтись по списку подавленных исключений.
                            Сообщение отредактировано: D_KEY -
                              Цитата D_KEY @
                              Тем не менее, в функциях очистки ошибки могут происходить. Например потому, что API ОС, как правило, предполагает коды ошибок для функций закрытия.
                              Естественно. Но любая такая хрень означает, что ошибка в программе. Например, почему CloseHandle() может упасть? Разве что из-за испорченнего HANDLE, который потёр кривой поинтер. Или потому, что тот уже закрыт. Когда все подобные ошибки будут исправлены, функции очистки тоже будут успешны.
                              Речь о том, что в безошибочной программе функции очистки никогда не столкнутся с такими ситуациями. Поэтому разрабатывать их с учётом подобных ситуаций нет необходимости. Если же такая необходимость возникла, то это значит лишь то, что программа плохо спроектирована, и некоторые действия в ней не должны размещаться в функциях очистки, т.к. не связаны с освобождением ресурсов. Помнишь, например, дискуссию о FreeAndNIL() в контексте Clear(), вызываемой в деструкторе? Там сами дельфисты нагородили костылей и пытались показать, что это нормально.
                              Сообщение отредактировано: Qraizer -
                                Цитата Qraizer @
                                Естественно. Но любая такая хрень означает, что ошибка в программе.

                                Проблема в том, что языки, в основном, предоставляют возможность "подавления" таких ошибок, т.к. ошибка может быть в сторонней либе, которую приходится использовать независимо от её кривости (например, если воркэроунд быстрее, проще и дешевле, чем повторная реализация нужного функционала без косяков). В итоге получаем, что ассерты и паники можно таки отловить, нивелируя их цель --- гарантированное падение программы и сигнализация о баге.
                                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                0 пользователей:
                                Страницы: (3) 1 [2] 3  все


                                Рейтинг@Mail.ru
                                [ Script execution time: 0,0584 ]   [ 16 queries used ]   [ Generated: 19.04.24, 00:05 GMT ]