На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
Модераторы: ANDLL, ALXR
Страницы: (12) 1 [2] 3 4 ...  11 12 все  ( Перейти к последнему сообщению )  
> #define ИЛИ template? , C++
   
#define ИЛИ template
Гости не могут просматривать результаты голосования.
Гости не могут голосовать 
    Очередной срачик на тему "коды возврата vs исключения"? :)
    Вообще, согласен с KILLER-ом - бояться забыть перехватить исключение и не бояться забыть проверить код возврата это прямо-таки образец двойных стандартов. Имхо, коды возврата можно предпочитать исключениям только при наличии в языке мощной системы типов, позволяющей писать обёртки вроде Either/Option, с которыми сам компилятор будет проверять, все ли возможные варианты возвращаемого значения ты рассмотрел. В языках же типа С/С++, а тем более C# они больше добавляют проблем, чем решают.
      Цитата Qraizer @
      Зачем? Во-первых, это известный legacy C паттерн, пол-POSIX-а так писано, к слову. Во-вторых, это тот же finally, только руками.

      Затем что об этом пошла речь. Можно писать и полный говнокод, а на вопрос - может отрефакторим - отвечать "зачем? Во первых, это известный legacy C паттерн, пол-POSIX-а так написано.".
        Цитата KILLER @
        Потому что, если ты избавляешься от goto(не меняешь поведение, поведение можно и с goto поменять), а именно стоит задача избавиться от goto.

        Избавиться от goto (я говорю о возврате ошибок) можно двумя способами:
        1) нагородить кучу if'ов. Очевидно, что это усложнит код.
        2) кидать исключения вместо того, чтобы возвращать код ошибки. Это решение уничтожит обратную совместимость.

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


        Цитата KILLER @
        А зачем нужно приложение, которое работает не верно? Вообще то по хорошему - лучше упасть, чем работать неверно.

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


        Цитата KILLER @
        Блин, я не понимаю как вы программируете? Ты юзаешь функцию и незнаешь - кидает она тебе исключение или нет?

        В общем случае ты не можешь гарантировать, что в документации перечислены все кидаемые исключения.

        Ну и у нас микс - С++ и C# :ph34r:
          Цитата Qraizer @
          Зачем? Во-первых, это известный legacy C паттерн, пол-POSIX-а так писано, к слову. Во-вторых, это тот же finally, только руками.

          Да, и к слову - чем хуже do/while + break ? По моему скромному мнению - это известный legacy C паттерн, который в 100 раз читабельней и структурированее, чем эти всякие goto.

          Добавлено
          Цитата Fester @
          1) нагородить кучу if'ов. Очевидно, что это усложнит код.
          2) кидать исключения вместо того, чтобы возвращать код ошибки. Это решение уничтожит обратную совместимость.

          3)
          ExpandedWrap disabled
            do
            {
                /*... Something...*/
               RetVal = GetLastError();
               if(RetVal != ERROR_SUCCESS)
                  break;
                
                /*Do something*/
               ....
            }while(false);
             
            //! Clean Up


          используя goto - от кучи if'ов - ты никуда не денешься. Посмотри хотя бы как используют goto на том же MSDN

          Добавлено
          Цитата Fester @
          Еще раз, само по себе использование goto - не есть зло.

          именно что самое по себе использование goto - зло. Потому как ты можешь прыгать по подпрограмме - взад-вперед, а это нарушает стуктурированность приложения, и куда ты там прыгнешь - предугадать в некоторых случаях без отладки нереально.

          Цитата Fester @
          Неверное оно может работать например из-за того, что неверно отработала какая-то железка.

          Да вот в твоем примере про деление, тебе возратило код возврата Деление на ноль, а ты не проверил код возврата, и записываешь результат в базу, причем не корректный результат. И к чему это потом приведет?

          Цитата Fester @
          В общем случае ты не можешь гарантировать, что в документации перечислены все кидаемые исключения.

          Тогда это уже не мои проблемы темболее. Ты тоже не можешь гарантировать что в документации перечислены все коды возврата.

          Цитата Fester @
          Ну и у нас микс - С++ и C# :ph34r:

          И что? Обычное дело через С++/cli. Какие проблемы?
            Странный опрос :)
            Можно показать примеры кода? В каком контексте сравниваем-то?
              Цитата KILLER @
              3)

              Это - типичный паттерн, пишущийся ради религиозной заморочки "лишь бы не было goto". Если пишешь на С, то goto cleanup по мне так удобней и читаемей, чем такой вот do{}while(false); В плюсах да, такое нафиг не надо.
                Цитата KILLER @
                Да, и к слову - чем хуже do/while + break ? По моему скромному мнению - это известный legacy C паттерн, который в 100 раз читабельней и структурированее, чем эти всякие goto.

                Ничем этот паттерн не лучше goto которого ты так боишься, ни в плане читаемости, ни тем более в плане работы/быстродействия.

                ExpandedWrap disabled
                    mem=malloc(size);
                    // ...
                    for(i=0; i<100; i++)
                    {
                      for(j=0; j<100; j++)
                      {
                        if(some_data[i][j]==SOME_VALUE) goto exit;
                        mem[i*100+j]=some_data[i][j];
                      }
                    }
                   
                  exit:
                    free(mem);
                    return 0;


                Напиши то же самое с do/while, for, break, continue и т.п. и без дублирования кода.

                Можно конечно написать
                ExpandedWrap disabled
                  if(some_data[i][j]==SOME_VALUE)
                  {
                    i=100;
                    break;
                  }

                или дублировать весь код очистки + return - но это ни разу не лучше будет читаться.
                Сообщение отредактировано: cppasm -
                  Цитата cppasm @
                  Ничем этот паттерн не лучше goto которого ты так боишься, ни в плане читаемости, ни тем более в плане работы/быстродействия.

                  Этот пример абсолютно не в тему. Вот вообще. Потому как я о нем писал выше.

                  Цитата OpenGL @
                  Это - типичный паттерн, пишущийся ради религиозной заморочки "лишь бы не было goto". Если пишешь на С, то goto cleanup по мне так удобней и читаемей, чем такой вот do{}while(false); В плюсах да, такое нафиг не надо.

                  Нет, ты видимо все таки не смотрел Microsoft SDK, где goto вхерачен в макрос, который представляет из себя часть какой то то ли функции, то ли проверки, и потом таким же макросом расставлены метки?
                  Это пичально. Этот пример лишь показывает как легко и не принужденно эмулировать goto, без потери читабельности. Будет у тебя 1 метка, и 1 переход - с этим можно жить. Но ты ведь не ходил по ссылкам, не смотрел код миркософта. И рассуждаешь об абстрактных конях в вакууме.
                  Избавится от goto - это нужно правильно проектировать архитектуру. А goto - для лентяев, и является очень частым источником ошибок, и заморочек. Либо ты только с академической стороны встречал goto в синтетических примерах, по этому так и рассуждаешь, либо рассматриваешь конкретный случай. Будет у тебя 2 метки, и два разных goto - ты уже сходу не врубишься в написанное. А я как то пытался рефакторить код, где на С понахерячили всю логику на goto вот такие же философы, которые не видят ничего плохого в goto. Встретил бы автора - оторвал бы руки. Потому как код я рефакторить не стал, я его просто удалил и написал все заного, без всяких goto, понятно и прозрачно.

                  Цитата cppasm @
                  Напиши то же самое с do/while, for, break, continue и т.п. и без дублирования кода.

                  Напишу. Но не сейчас. Я сейчас занят. Но идея такова - избавится от вложенного цикла. Твой код синтетический и надуманный. Ты хочешь сказать его не реально по другому переписать никак? Я если что в него даже не в никал, просто по диагонале посмотрел не особо вдумываясь в смысл написанного.
                  Сообщение отредактировано: KILLER -
                    Цитата KILLER @
                    Этот пример абсолютно не в тему. Вот вообще. Потому как я о нем писал выше.

                    Чем он не в тему?
                    Ты же писал что
                    Цитата KILLER @
                    именно что самое по себе использование goto - зло.



                    Цитата KILLER @
                    Нет, ты видимо все таки не смотрел Microsoft SDK, где goto вхерачен в макрос, который представляет из себя часть какой то то ли функции, то ли проверки, и потом таким же макросом расставлены метки?
                    Это пичально.

                    Это печально что ты не приводишь конкретных примеров, а только бла бла бла...
                    По ссылкам твоим ходил - нигде там такого нету.
                    В основном везде переход на Cleanup из середины функции.


                    Цитата KILLER @
                    Но идея такова - избавится от вложенного цикла. Твой код синтетический и надуманный.

                    Во-первых код не надуманный, а упрощённый.
                    Никогда при написании кода не возникало необходимости вывалиться из нескольких вложенных циклов?
                    Во-вторых идея избавиться от вложенных циклов только потому что тебе goto не нравится фиговая, т.к. в реальных условиях от вложенных циклов избавиться получится далеко не всегда.
                      Цитата KILLER @
                      Можно писать и полный говнокод, а на вопрос - может отрефакторим - отвечать "зачем? Во первых, это известный legacy C паттерн, пол-POSIX-а так написано.".
                      Можно и говнокод писать. Но лучше не надо. А патерн, как бы тебе лично не хотелось, он патерн. Его знают, узнают с пол-взгляда и сразу понимают, что он делает и зачем вообще нужен. Ну, те, кто о нём знает, конечно. Я вот из декоратора знаю только название, и уже не помню, зачем он собственно нужен, так что запросто, увидев в твоём коде и не распознав, заору "говнокод". Буду ли я прав?.. зависит от обстоятельств, не так ли? Твои апелляции к примерам MSDN – это не те обстоятельства, когда говнокод, и я объяснил, почему.

                      Добавлено
                      Цитата KILLER @
                      Да, и к слову - чем хуже do/while + break ? По моему скромному мнению - это известный legacy C паттерн, который в 100 раз читабельней и структурированее, чем эти всякие goto.
                      По меньшей мере тем, что это не патерн обработки ошибок. А ещё тем, что обработка ошибок зачастую ломает структурность алгоритма. Напрочь. Попытки обернуть неструктурность алгоритма в фантик структурности наивны, т.к. наносят вред.
                      Сообщение отредактировано: Qraizer -
                        Цитата KILLER @
                        В С есть константы, на сколько я помню, так что такое оправдание не катит.
                        Константы в C это всего лишь переменные, в которые не разрешается писать. Размещаются они там в точности так же, как и переменные без модификатора const. То есть в одной единице трансляции пишется
                        ExpandedWrap disabled
                          double const R2C = 273.15;
                        в остальных
                        ExpandedWrap disabled
                          extern double const R2C;
                        иначе при сборке вылетает сообщение о дублировании имён.
                        То есть, только при трансляции одного куска известно значение этой константы, из остальных можно только прочитать его из памяти.
                        Соответственно нельзя использовать такую константу для определения, например, размера массива. Кроме того, такая константа не участвует в вычислении константных выражений.

                        Определение константы как
                        ExpandedWrap disabled
                          static double const R2C = 273.15;
                        делает доступным её значение в каждой единице трансляции, но компилятор всё равно резервирует для каждой такой константы место (отдельное в каждой единице, где она определена), и тоже не разрешает использовать её для задания тех же размеров, и не вычисляет выражения с её использованием.

                        Некоторые компиляторы, конечно, позволяют себе соптимизировать использование таких констант, но это как раз нестандартное поведение.
                        Сообщение отредактировано: amk -
                          Цитата KILLER @
                          Нет, ты видимо все таки не смотрел Microsoft SDK, где goto вхерачен в макрос, который представляет из себя часть какой то то ли функции, то ли проверки, и потом таким же макросом расставлены метки?

                          Причём тут MS SDK? Я ответил на конкретный пример - когда с помощью goto переходят к очистке локальных ресурсов, то это вполне удобно и читабельно (если в языке нет иных для этого механизмов), в отличие от твоего исправления. А про примеры от MS я, в общем-то, речь не вёл, а просто спросил, где там говнокод с твоей точки зрения.

                          Цитата KILLER @
                          Напишу. Но не сейчас. Я сейчас занят. Но идея такова - избавится от вложенного цикла. Твой код синтетический и надуманный. Ты хочешь сказать его не реально по другому переписать никак? Я если что в него даже не в никал, просто по диагонале посмотрел не особо вдумываясь в смысл написанного.

                          Оно и видно. Код вполне нормальный, задача - прервать выполнение цикла, если что-то пошло не так. Т.е. хватит даже простого цикла (не обязательно двойного-тройного), из которого нужно переходить к очистке, чтобы твой паттерн с do..while перестал работать. Только не говори "не юзать циклы вообще" - такое будет даже от тебя неадекватно звучать :D
                            Цитата KILLER @
                            ну может быть еще какую вещь упустил

                            Ага :lol: макро assert
                            У меня есть хороший макро для целей анализа ... бета-версий, а-ля:
                            ExpandedWrap disabled
                              #define GuiCheckFatal() if (!Global.Error.isEmpty()) { QMessageBox::critical(0, QObject::tr("Внимание!"), Global.Error + QObject::tr("<hr>Файл: \"")+QFileInfo(__FILE__).fileName()+QObject::tr("\"<BR>Строка: ")+QString::number(__LINE__)); qCritical() << Global.Error + QObject::tr(" Файл: \"")+QFileInfo(__FILE__).fileName()+QObject::tr("\" Строка: ")+QString::number(__LINE__); Global.Error.clear(); qApp->closeAllWindows(); return; }

                            При условии перехвата записи в qCritical() и реализации записи в лог файл - мой макро божественен!
                            Не знаю что бы я делал без #define
                              Цитата cppasm @
                              Чем он не в тему?
                              Ты же писал что

                              Он не в тему тем, что ты пришел, тему не читал, зато начал что то писать. Я тебе говорю - твой пример не в тему, и не привожу почему - чтоб ты взял и сам перечитал. А ты судя по всему не перечитал, делаешь глупое лицо и спрашиваешь - чем? Вот сиди и ломай голову. Раз тебе перечитывать лень.

                              Цитата cppasm @
                              Это печально что ты не приводишь конкретных примеров, а только бла бла бла...

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

                              Цитата cppasm @
                              Во-первых код не надуманный, а упрощённый.

                              Надуманный.

                              Цитата cppasm @
                              Никогда при написании кода не возникало необходимости вывалиться из нескольких вложенных циклов?

                              Абсолютно никогда. Даже припомнить таких случаев не могу. Всегда обходился без этого треша. Более того, я тебе больше скажу - у меня никогда за 15 лет - не возникало даже мысли чтобы вот тут юзнуть goto, потому что без него вообще никак не сделать.

                              Ты может приведешь такой пример? А не просто надуманный говнокод? Который ты не в состоянии преписать по нормальному?

                              Цитата cppasm @
                              Напиши то же самое с do/while, for, break, continue и т.п. и без дублирования кода.

                              А зачем ты мне ставишь такие ограничения? Ты че, думаешь я тут распинатся буду и переписывать тебе с do/while? Ну извини, я не мыслю такими категориями как goto, я тебе больше скажу - он мне ниразу в жизни никогда не понадобился. И я даже не представляю задачи - где без него нельзя было бы обойтись. Ну не считая вот таких вот выдуманных говнокодов, или каких нибудь костылей - где по другому не перепишешь быстро.
                              По поводу кода - на держи:
                              ExpandedWrap disabled
                                int iterateRow(void* mem, int col)
                                {
                                        for(j=0; j<100; j++)
                                        {
                                          if(some_data[col][j]==SOME_VALUE)
                                               return some_data[col][j];
                                          mem[col*100+j]=some_data[col][j];
                                        }
                                   return 0;
                                }
                                 
                                void main()
                                {
                                    mem=malloc(size);
                                      // ...
                                      for(i=0; i<100; i++)
                                      {
                                          if( iterateRow(mem, i)==SOME_VALUE )
                                               break;
                                      }
                                 
                                      free(mem);
                                      return 0;
                                 
                                }


                              Цитата cppasm @
                              По ссылкам твоим ходил - нигде там такого нету.
                              В основном везде переход на Cleanup из середины функции.

                              Да никуда ты не ходил. Кому ты лапшу вешаешь? Максимум ты ткнул на пример с MSDN, и по "See Also" еще глянул пару примеров.

                              Цитата cppasm @
                              Во-первых код не надуманный, а упрощённый.

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

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

                              Хорошо, кинь мне ссылку на описание этого паттерна, впервые о таком слышу. Может тоже буду применять у себя. А то я хочу из умной книжки почитать - его название, какие у него есть плюсы, какие у него есть минусы, и какие есть альтернативные варианты, когда его лучше использовать, а когда нет.
                              И не нужно отвечать на эти вопросы - ты же понимаешь что они риторические. Мне нужна именно ссылка на описание этого паттерна. Я хочу убедиться, что это именно паттерн, а не просто говнокод лентяев, которым лень переписывать по другому.

                              Цитата Qraizer @
                              По меньшей мере тем, что это не патерн обработки ошибок. А ещё тем, что обработка ошибок зачастую ломает структурность алгоритма. Напрочь. Попытки обернуть неструктурность алгоритма в фантик структурности наивны, т.к. наносят вред.

                              А зачем придумывать неструктурированный алгоритм? Или goto не ломает структурированность? Я что то ничего не понял.

                              Цитата OpenGL @
                              Причём тут MS SDK?

                              При том, что я писал про код микрософта:
                              Цитата KILLER @
                              Да вообще у майкрософта подход к программированию какой то нубско-студенческий. Всюду юзают goto и где не попадя макросы, даже вместо констант. Порой смотришь их MSDN или код какой нибудь функции и диву даешься - неужели там действительно тупарей берут, которые без макросов и goto писать не могут ниче.

                              Если они так пишут свое SDK, значит они ровно так же пишут свой продуктивный код. Более того - я с их кодом очень часто пересекаюсь, и вижу какой у них подход к написанию кода. И если бы это касалось только кода 80-х годов, у меня бы не было никаких притензий.

                              Цитата OpenGL @
                              Я ответил на конкретный пример - когда с помощью goto переходят к очистке локальных ресурсов, то это вполне удобно и читабельно (если в языке нет иных для этого механизмов), в отличие от твоего исправления. А про примеры от MS я, в общем-то, речь не вёл, а просто спросил, где там говнокод с твоей точки зрения.

                              И часто ты так делаешь? :lol: Что реально удобно? Если это удобно и читабельно - значит ты так же делаешь? Или ты просто с академической стороны вопроса судишь? Или ты - я так никогда не делаю, но это удобно? Нихрена это не удобно. Это напрочь ломает читабельность кода.

                              Цитата OpenGL @
                              А про примеры от MS я, в общем-то, речь не вёл, а просто спросил, где там говнокод с твоей точки зрения.

                              Везде. Я тебе уже отвечал. И привел алгоритм действий. Если ты его не осилил - это уже не мои проблемы.

                              Цитата OpenGL @
                              Оно и видно. Код вполне нормальный, задача - прервать выполнение цикла, если что-то пошло не так.

                              Здача может и стандартная, но вот реализация - говнокод. Что по другому никак нельзя прервать выполнение цикла? Лично для меня вот тот код выше, что привел cppasm, дикость. Я лично считаю что так пишут люди ограниченные в умственных способностях. Возможно я так думаю потому, что мне еще не приходилось страдать таким и сталкиваться с этим. А значит - либо такая ситуация - очень редкая и не стандартная и не стоит обсуждения. Либо пишут так говнокодеры, которым лень думать. Но ты если что не обижайся, это лично мое мнение. Я не претендую на истину, и в полне могу ошибаться.
                              Особенно если ты покажешь мне не синтетическую задачу, а какую нибудь боевую, где без этого goto, как без ifndef в кроссплатформенном коде. Может быть тогда я изменю свое мнение. Пока что для меня это говнокод.

                              Цитата OpenGL @
                              из которого нужно переходить к очистке, чтобы твой паттерн с do..while перестал работать. Только не говори "не юзать циклы вообще" - такое будет даже от тебя неадекватно звучать :D

                              Еще раз - do/while - Лично для меня воспринимается гораздо лучше и читабельнее, чем goto, потому что нет меток и скачков. У тебя есть цикл, и есть break, все. Тебе не нужно искать метку глазами, а блок где заканчивается цикл, мне и IDE подсветит на крайняк.

                              Добавлено
                              Цитата JoeUser @
                              У меня есть хороший макро для целей анализа ... бета-версий, а-ля:
                              CollapsedWrap disabledLine numbers off

                              Это отладочные средства. Про них речи не идет. То что есть у тебя, и то что ты применяешь для себя, и то что это никуда не идет - касается лично тебя. Соответственно ты можешь писать там как угодно, никто тебе слово не скажет. Вот если это попадает в прод, тогда другое дело.

                              Добавлено
                              Цитата cppasm @
                              Ничем этот паттерн не лучше goto которого ты так боишься

                              Да, и к слову, я goto не боюсь. Просто для меня это сродни кучке говна. Ты ведь не боишься говно? Но считаешь его противным? Вот примерно вот так для меня goto. Вижу goto - это значит, автор расписался в собственном бессилии и навалил кучку говнеца в коде.
                              Сообщение отредактировано: KILLER -
                                Цитата KILLER @
                                И часто ты так делаешь?

                                Попробуй ответить на этот вопрос самостоятельно. Тебе для этого надо знать только то, что я не пишу на Си - остальную информацию для ответа ты можешь получить из моих постов этой темы. :D

                                Цитата KILLER @
                                Я тебе уже отвечал.

                                Я знаю, что ты отвечал. Ты подумал что ли, что я это ещё раз спрашиваю? :lool: Да, я от тебя на данный конкретный вопрос ответ получил, он меня впоне устроил и новых вопросов по этому поводу у меня нет. Можно считать вопрос о говнокоде в MS SDK закрытым, или я всё ещё недостаточно ясно выразился, что я с этим не спорю от слова совсем? :D

                                Цитата KILLER @
                                Особенно если ты покажешь мне не синтетическую задачу, а какую нибудь боевую, где без этого goto, как без ifndef в кроссплатформенном коде. Может быть тогда я изменю свое мнение. Пока что для меня это говнокод.

                                Киля, перечитай внимательней. Простейший паттерн:
                                1) сложная инициализация локальных переменных
                                2) главные действия, которые могут прерваться из разных мест, после чего надо перейти в 3)
                                3) очистка того, что создали в 1)

                                твоим паттерном do..while более читабельным не сделать, если в 2 у тебя есть циклы, из которых ты можешь выходить сразу в 3). Ну и до кучи могу напомнить эту тему - в ней был пример, когда с помощью goto вообще заходят внутрь тройного цикла, и более читабельный вариант того примера, но без goto, никто, включая тебя, так и не родил.
                                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                0 пользователей:
                                Страницы: (12) 1 [2] 3 4 ...  11 12 все


                                Рейтинг@Mail.ru
                                [ Script execution time: 0,0826 ]   [ 18 queries used ]   [ Generated: 29.03.24, 05:33 GMT ]