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

    Регламент

    1) Спорим обо все, что касается или должно касаться Цэ++
    2) Любые темы сводим к возможностям Цэ++
    3) Если модератор "снесет" тему из раздела Цэ++, ожидайте наплыв прогеров на васике. Лично я забью на нее.
      D_KEY, с этим я согласен. D сюда принес топикстартер. Срезать и перенести в соответствующий холивор, если Qraizerу будет не лень. Или вовсе поудалять.
      Сообщение отредактировано: applegame -
        А что плохого в примесях D, если есть частичная реализация в Цэ++? Что за паталогическая тяга стараться оставлять темы только типа "а как выделить память в функции?". Вам самим от этого не скушно?

        Добавлено
        Цитата JoeUser @
        Ты хотел сказать "инкапсуляции"?

        Кстати, инкапсуляция с помощью примесей так же - в наличии. Пруф:
        Скрытый текст
        ExpandedWrap disabled
              import std.stdio;
              
              mixin template Foo() {
                  int z = 10;
                  void func() { writeln("Foo.func()", z); }
              }
              
              class Bar {
                  mixin Foo;
              }
              
              class Code : Bar {
                  override void func() { writeln("Code.func()",z); }
              }
              
              void main() {
                  Bar b = new Bar();
                  b.func();      // calls Foo.func()
                  b = new Code();
                  b.func();      // calls Code.func() <---------- печатает 10
              }
          Цитата JoeUser @
          А что плохого в примесях D, если есть частичная реализация в Цэ++?
          Ничего плохого, просто как можно обсуждать примеси в контексте C++?
          Цитата JoeUser @
          Кстати, инкапсуляция с помощью примесей так же - в наличии. Пруф:
          Да не о инкапсуляции речь, а о полиморфизме. Вот тебе код на C++, попробуй его заменить примесями:
          #include <iostream>
          ExpandedWrap disabled
            using namespace std;
            #include <iostream>
            using namespace std;
            class Foo {};
            class Bar {};
            class Poly: public Foo, public Bar {};
             
            void func1(Foo foo) {}
            void func2(Bar bar) {}
             
            int main() {
                Poly poly;
                func1(poly);
                func2(poly);
                return 0;
            }
            Хотя, блин! Посыпаю голову пеплом!!! :wall: Не инкапсуляция - "наследование". Инкапсуляция в классах по факту.
              Цитата applegame @
              Да не о инкапсуляции речь, а о полиморфизме. Вот тебе код на C++, попробуй его заменить примесями:

              Понял. Осознал. Согласен. Следствие подходов языка. И примеси тут только (в определенных случаях) синтаксический сахар. А замена множественного наследования:
              1) Множественное наследование интерфейсов
              2) Множественное наследование подтипов
              Что, кстати, тоже очень даже неплохо укладывается в логику. По факту, множественное наследование - это не самоцель, а способ достижения функционала и данных наследников. А как это будет сделано - количество строк кода покажет ;)
                Цитата applegame @
                Зачем, если уже есть особый вид "исключений" - assert. Если ты опасаешься, что не все еще отлажено, можешь не убирать ассерты в релизе.
                В том-то и прикол, что опасаться нужно всегда. Откуда уверенность, что под-assert()-ные проверки больше не потребуются никогда в жизни на протяжении жизненного цикла? assert() с его abort()-ом был более-менее приемлем для C, но там и <setjmp.h> вполне себе в теме. Исключения в C++ были введены с той же целью, что и <csetjmp>, однако они в отличие от нелокальных прыжков совместимы с локальными объектами в общем и RAII в частности. Если abort() хоть как-то обоснован в C, там нет объектов, то в C++ его ниша исчезающе мала, если не вообще нулевая.

                Добавлено
                Цитата JoeUser @
                Для чего придумали блок кэтч? Для последующей ловли, и возможно корректной обработки исключительной ситуации, как следствие - возможного нормального исполнения программы. Ассерты же - это финиш с посмертным выбросом инфы.
                Это лирика. Главное назначение исключений в предоставлении способа осуществления нелокальных переходов, безопасного к инвариантам. Как этот механизм будет использован программистом – это его личное дело. По ряду причин считается, что исключения должны использоваться в исключительных случаях. Под таковыми лично я вижу только (цитата из стандарта кодирования моего в частности авторства):
                Цитата
                • Невозможность функции/методу исполнить свой контракт при невозможности вернуть признак ошибки. Примером может служить функция, возвращающая ссылку на объект в случае невозможности создать таковую, т.к. ссылок на NULL не существует.
                • Невозможность конструктору закончить создание инвариантов для экземпляра класса, например, в связи с исчерпанием ресурсов. В соответствие с тут ссылка на предшествующий раздел создание неработоспособных объектов крайне не приветствуется, а недоконструированных – запрещено объектной моделью языка. Поэтому исключение из конструктора является единственно надёжным способом надёжно предотвратить использование невалидного объекта. Любой другой способ не даёт 100% гарантии.
                • При крайней необходимости осуществить нелокальный переход в стиле <csetjmp>. Использование нелокальных переходов в стиле C вне исключительно C-кода запрещено в связи с их негарантирующей отказоустойчивостью.
                Это не догма, конечно, однако нетрудно видеть, что этими случаями исчерпываются все возможные случаи, когда без исключений не обойтись. Внезапно выясняется, что assert()-ы прекрасно подходят под первый случай, т.к. их назначение как раз в проверке предусловий, которые никогда не должны нарушаться.
                  Цитата Qraizer @
                  Как этот механизм будет использован программистом – это его личное дело. По ряду причин считается, что исключения должны использоваться в исключительных случаях.


                  Золотые слова :lol: Есть возможность использования, есть ограничения - остальное дело фантазии. "Считается" - не в счет, это демагогия. Есть здравый смысл. Пример синтаксиса:

                  функция() {
                  }

                  функция()
                  {
                  }

                  функция() { }

                  Здравый смысл подсказывает, что оформление первых двух функций удобно, третьей - если она на залезает за границы экрана. Иначе неудобно. Так и с исключениями - их можно везде использовать, где можно. Главное, чтобы логика не ломала моск. Обработка "обрабатываемых" ситуаций - тут ни разу не противоречит здравому смыслу. Следовательно придавать смысл "исключительным" ситуациям значения "фатально-непоправимых" - есть субъективное аффторство субъективного аффтора. Имхо.
                    Конечно. Но есть нюанс.
                    К примеру субъективное мнение автора сказало ему, что использовать исключения для управления потоком исполнения вполне себе удобно и нормально. Т.е. он решил построить свой код на архитектуре, шитой процитированной выше третьей причиной. Получается, что субъективное мнение автора убедило его, что нелокальные переходы – это нормально и удобно. Пусть теперь сей автор подумает и заценит, что скажут о его коде другие, если б он писал его в стиле С, т.е. на <setjmp.h>. Как бы "ненуачё, мне нужны нелокальные переходы" разбивается об холивар о goto.
                      Цитата Qraizer @
                      Использование нелокальных переходов в стиле C вне исключительно C-кода запрещено в связи с их негарантирующей отказоустойчивостью.
                      Более того, обычно не то что "негарантированно отказоустойчиво", а как правило даже "гарантированно отказосоздающе". Иногда даже в рамках чистого C-кода.
                        Цитата Qraizer @
                        Получается, что субъективное мнение автора убедило его, что нелокальные переходы – это нормально и удобно.

                        Если это не ломает читабельный стиль и одновременно не приносит излишних расходов по производительности, объему кода - я ничего предосудительного не вижу. Тем более, если мы говорим о структурной обработке исключения, то сам термин "структурная" говорит о том, что пишем нормально, а не левой ногой.
                          Нет, мы говорим о C++EH.

                          P.S. Оффтоп. Кстати, кто тебе сказал, что "структурная", которая SEH, имеет какое-то отношение к структурному программированию? Это всего лишь означает, что структурно оформляются охраняемые блоки и блоки обработки. Однако переходы по этим блокам – это не просто какие-то там goto, которые прыгают строго по статичным меткам. Это вычислимые goto, которые прыгают невесть куда, это только в run-time будет известно.
                            Ну это понятно, там, на сколько я понимаю, еще и раскрутка стека. Ну так - это не единственный сюрприз Цэ++. Возьми те же неявные конструкторы. Мало-ли как "оно, то или другое" там внутри работает - главное как мы видим и правильно ли оформляем.

                            И второй момент, раз нам дана возможность наследоваться от классов исключений - значит это возможность, и ею законно можно пользоваться.
                              Цитата Qraizer @
                              В том-то и прикол, что опасаться нужно всегда. Откуда уверенность, что под-assert()-ные проверки больше не потребуются никогда в жизни на протяжении жизненного цикла?
                              Убирание ассертов из релиза не является неотъемлемым их свойством. Если ассерты дают существенный минус к производительности у тебя всегда есть выбор пожертвовать ассертами ради производительности. Я вовсе не утверждаю, что ассерты необходимо обязательно удалять из релиза.
                              Цитата Qraizer @
                              assert() с его abort()-ом был более-менее приемлем для C, но там и <setjmp.h> вполне себе в теме. Исключения в C++ были введены с той же целью, что и <csetjmp>, однако они в отличие от нелокальных прыжков совместимы с локальными объектами в общем и RAII в частности. Если abort() хоть как-то обоснован в C, там нет объектов, то в C++ его ниша исчезающе мала, если не вообще нулевая.
                              Я вот не пойму зачем сравнивать исключения/setjmp с ассертами? Ассерты - это завершение программы в случае обнаруженного UB, в тоже время как исключения/setjmp - вполне себе определенное поведение. Допустим произошло нарушение некоторого контракта по неведомым причинам. Объект стал невалидным и дальнейшее выполнение программы (в том числе и раскрутка стека, вызов деструкторов и т.п.) превращается в сплошное UB. Накой тут исключение/setjmp? Единственный верный путь в данном случае - диагностическое сообщение и аварийное завершение программы.
                              Цитата Qraizer @
                              Это лирика. Главное назначение исключений в предоставлении способа осуществления нелокальных переходов, безопасного к инвариантам. Как этот механизм будет использован программистом – это его личное дело.
                              Можно подумать что вот это твое личное спорное мнение - не лирика. Назначение исключений - предоставление возможности выполнить нелокальный переход??? Нет, я конечно не спорю, что исключение можно с некоторой натяжкой назвать нелокальным переходом, но это ни разу не его (исключения) назначение. Назначение исключений - обеспечивание удобной обработки не просто исключительных, а ожидаемо исключительных событий.
                              Цитата Qraizer @
                              Невозможность функции/методу исполнить свой контракт при невозможности вернуть признак ошибки. Примером может служить функция, возвращающая ссылку на объект в случае невозможности создать таковую, т.к. ссылок на NULL не существует.
                              Подчеркнутое спорно. При желании любая функция может вернуть признак ошибки, возвращая кортеж из результата и флага ошибки. Вроде в Rust именно такой подход. Тут скорее дело не в возможности/невозможности вернуть код ошибки, чистой воды религиозные запреты. Правда возврат ссылок на не существующие объекы действительно проблема, но при желании таки можно создать ссылку на null. :)
                              Цитата Qraizer @
                              При крайней необходимости осуществить нелокальный переход в стиле <csetjmp>. Использование нелокальных переходов в стиле C вне исключительно C-кода запрещено в связи с их негарантирующей отказоустойчивостью.
                              Да, но повторяю, assert- это не нелокальный переход. Ассерт не просто не гарантирует отказоустойчивость, а напротив гарантирует отказ.
                              Сообщение отредактировано: applegame -
                                applegame, я был бы не против assert()ов, если, во-первых, использовать их наоборот – для выявления мест возникновения багов вместо контроля их отсутствия; во-вторых, вместо abort() они бы плюхали мне отладчик на монитор. Однако первое оказывается ненужным после выявления места бага, второе невозможно по определению assert()-а в Стандарте. Так что фтопку.
                                Цитата applegame @
                                Я вот не пойму зачем сравнивать исключения/setjmp с ассертами? Ассерты - это завершение программы в случае обнаруженного UB, в тоже время как исключения/setjmp - вполне себе определенное поведение. Допустим произошло нарушение некоторого контракта по неведомым причинам. Объект стал невалидным и дальнейшее выполнение программы (в том числе и раскрутка стека, вызов деструкторов и т.п.) превращается в сплошное UB. Накой тут исключение/setjmp? Единственный верный путь в данном случае - диагностическое сообщение и аварийное завершение программы.
                                Я и не сравниваю. Я утверждаю, что assert() бесполезен, у него тупо нет вменяемой ниши. Предположим, да, произошло нарушение инварианта. И что? Это проблема конкретного экземпляра конкретного класса. Если это единственный класс на всю программу, а ещё лучше единственный экземпляр этого класса, то соглашусь. Да, конкретно вот это – ниша assert()-а. В любом же другом случае, объясни, плз, чем провинились другие классы и экземпляры? Тут тоже можно найти нишу, в особых классах с высочайшим уровнем ответственности и влиянием на всё операционное окружение, только она исчезающе мала.
                                А проблема конкретного экземпляра конкретного класса решается куда изящнее ...исключением, которое нигде не перехватывается. Поставил обработчик неперехваченных, получил в нём это особое исключение, вытащил оттуда нужную инфу, молотком привёл экземпляр во вменяемое состояние, заменил на нормальное исключение, бросил, размотал стек и вышел.
                                Цитата applegame @
                                Назначение исключений - предоставление возможности выполнить нелокальный переход??? Нет, я конечно не спорю, что исключение можно с некоторой натяжкой назвать нелокальным переходом, но это ни разу не его (исключения) назначение. Назначение исключений - обеспечивание удобной обработки не просто исключительных, а ожидаемо исключительных событий.
                                Назначение исключений – заменить <csetjmp>, а уже назначение последнего – нелокальные переходы. Вывод ИМХО очевидный. Можно использовать средства не по их назначению, ничего плохого в этом нет. Кроме как если такое использование неоправданно.
                                Цитата applegame @
                                Подчеркнутое спорно. При желании любая функция может вернуть признак ошибки, возвращая кортеж из результата и флага ошибки.
                                Да. Но в большинстве случаев это неудобно и ненадёжно. Заметь, то цитата из стандарта кодирования, поэтому надёжный код – это основная мотивация его пунктов. С моей точки зрения в критически важных для надёжности случаях нельзя оставлять человеку возможность ошибиться и забыть проверить состояние ошибки. Исключение проигнорить не получится, а если такое и произойдёт... то это не ассерт, в конце концов.
                                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                0 пользователей:
                                Страницы: (15) 1 2 [3] 4 5 ...  14 15 все


                                Рейтинг@Mail.ru
                                [ Script execution time: 0,0628 ]   [ 15 queries used ]   [ Generated: 2.05.24, 08:36 GMT ]