На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! Правила раздела:
1. Название темы - краткое описание кто/что против кого/чего
2. В первом сообщении - список параметров, по которым идет сравнение.
3. Старайтесь аргументировать свои высказывания. Фразы типа "Венда/Слюникс - ацтой" считаются флудом.
4. Давайте жить дружно и не доводить обсуждение до маразма и личных оскорблений.
Модераторы: Модераторы, Комодераторы
Страницы: (32) « Первая ... 25 26 [27] 28 29 ...  31 32  ( Перейти к последнему сообщению )  
> goto vs break & continue , Кроха-сын пришел к отцу и спросила кроха: "goto - это хорошо?"
    Цитата Wound @
    Нет, не с тем же успехом. Если убрать его багу, допустим выкинуть scope(exit) вообще из его программы, никаких сигфолтов нет. Его программа абсолютна правильная и рабочая на языке D.
    Нет его программа неправильная. Он неверно оценил время жизни объектов. Представь себе, что чувак написал вместо scope() RAII-обертку, в деструкторе которой вызвал этот свой TTF_Quit(). Все также грохнется без всякого scope().
    Цитата Wound @
    Но не в С++, вот в этом и состоит существенная разница. Для С++ эта программа багнутая.
    Я хз, как ты оценил багнутость дешной программы с точки зрения C++. Эти языки хоть и сильно похожи, но также и сильно разные. В D можно вообще не освобождать память и утечек не будет, а для C++ утечки будут, и что, эти программы будут багнутые? Бессмыслица какая-то.
    Цитата Wound @
    В Dшном примере - ручное управление ресурсом в перемешку с автоматическим GC.
    Именно, вот это главная причина, чувак вступил на теневую территорию, а там легко выстрелить себе в ногу. Аналогично было у меня, когда я попытался перемешать shared_ptr со своими RAII обертками. Это было когда я изучал boost::asio. Забавно, но в относительно сложных системах вроде boost::asio, shared_ptr фактически теряет свою детерминированность и становится очень похож на обычный GC. Очень похоже на вот этот твой пример.
    Цитата Wound @
    Ну я не знаю с чем ты споришь. В Dшном примере - ручное управление ресурсом в перемешку с автоматическим GC.
    Я спорю с тем, что scope(exit) тут не причем. scope(exit) просто выполняет код при выходе из скоупа - все. Если этот код некорректен и приводит к сегфолту, то причем тут сам scope(exit)? Допустим ты написал цикл for в теле которого сделал что-то нехорошее и оно у тебя упало. По твоей логике получается, что цикл for опасен и применять его нужно с осторожностью.

    Добавлено
    Цитата Wound @
    Чем твоя функция будет отличаться от Сишной функции с теми же goto ?
    Тем что в моей функции нет goto? :-?
    Цитата Wound @
    Я думаю, что если бы этот scope(exit) был таким же крутым как RAII, то во всяких Java/C# он давно бы уже был, вместо этих ваших using/try-with-resources, которые имитируют как раз RAII, с принудительным вызовом деструктора.
    Возможно и появятся. Ты же нашел экспериментальныек scope в плюсах. :) Кроме того, еще есть scope(success) и scope(failure).
    Цитата Wound @
    В случае с RAII ты пишешь инициализацию/удаление отдельно, и забыть написать удаление - конечно можно, но это довольно не тривиальная задача. А потом просто юзай и все, не заботясь о том в каком там порядке что у тебя вызывается, или когда там нужно очистить если исключение произошло или еще что то, сам компилятор за тебя все очистит правильно и гарантированно в нужном порядке.
    Тут похоже, ты один раз пишешь функцию-обертку, отлаживаешь ее (точно так же как и ты свою RAII-обертку) и используешь много раз не заботясь об освобождении ресурса. Повторю, это не всегда удобнее традиционного RAII.
    Я ничего не имею против RAII и сам им актовно пользуюсь. Но я привожу примеры, где scope(exit) проще и понятнее и не менее безопасно, чем RAII. Вы же мне в ответ приводите другие примеры, где RAII уместнее. Получается странный и бестолковый спор.

    Добавлено
    Ну и наконец. Прошу все же учесть, что scope(...) это не только про RAII. scope это скорее про try/catch/finally. Вот коротенькая глава из книжки по D о скоупах, если интересно:
    http://ddili.org/ders/d.en/scope.html
    Сообщение отредактировано: applegame -
      Цитата applegame @
      Нет его программа неправильная. Он неверно оценил время жизни объектов. Представь себе, что чувак написал вместо scope() RAII-обертку, в деструкторе которой вызвал этот свой TTF_Quit(). Все также грохнется без всякого scope().

      Ну как не правильная, я же говорю не про текущий пример, а вообще выкинь scope(exit) - его программа правильная, я имею ввиду что ему не нужно вызывать потом delete a; т.к. у него есть GC, соответственно он на него и положился. В случае с С++ такой ситуации не будет, потому что не будет scope(exit), вместо него будет своя RAII обертка. Далее ресурс который должен уничтожиться до scope(exit) - будет агрегатом этой RAII обертки.

      Цитата applegame @
      Я хз, как ты оценил багнутость дешной программы с точки зрения C++. :lol: Эти языки хоть и сильно похожи, но также и сильно разные. В D можно вообще не освобождать память и утечек не будет, а для C++ утечки будут, и что, эти программы будут багнутые? Бессмыслица какая-то.

      А что там оценивать? Вот смотри:
      ExpandedWrap disabled
            import std.stdio;
            
            struct De
            {
                ~this() { writeln("De"); }
            }
            
            void main()
            {
                auto a = new De();
            }

      Тут есть ошибки, если писать на D? В С++ в таком виде есть ошибка, а в D?


      Цитата applegame @
      Именно, вот это главная причина, чувак вступил на теневую территорию, а там легко выстрелить себе в ногу. Аналогично было у меня, когда я попытался перемешать shared_ptr со своими RAII обертками. Это было когда я изучал boost::asio. Забавно, но в относительно сложных системах вроде boost::asio, shared_ptr фактически теряет свою детерминированность и становится очень похож на обычный GC. Очень похоже на вот этот твой пример.

      Я что то не понял, в чем ошибка? У shared_ptr есть своя болезнь с циклическими ссылками.

      Цитата applegame @
      Я спорю с тем, что scope(exit) тут не причем. scope(exit) просто выполняет код при выходе из скоупа - все. Если этот код некорректен и приводит к сегфолту, то причем тут сам scope(exit)? Допустим ты написал цикл for в теле которого сделал что-то нехорошее и оно у тебя упало. По твоей логике получается, что цикл for опасен и применять его нужно с осторожностью.

      Ну как не причем? Представь его бы не было. Как бы ты все это писал? Естественно на RAII каком нить, и у тебя такой ситуации просто не возникло бы.

      Вот возьми goto - чем он плох? Он такой же как return/continue/break/for/while/etc, он ничем не хуже этих операторов. Но его почему то все ругают. А потому что если им увлечься, то ты будешь писать "как проще", но совсем не "качественно", да вон даже отмотай на 5 страниц назад. Чувак пишет - накой мне писать и городить классы и какие то обертки, если я взял вызвал goto clean: и все. 10 букв, против целого класса!!! Так же и с этим. Тебе не нужно думать и замарачиваться каким то обертками, ты взял вот тут юзнул scope(exit), а в другом месте забыл его вызвать. И вуаля.

      Цитата applegame @
      Тем что в моей функции нет goto?

      Т.е. по сути твой пример со scope(exit) ничем не отличается от того же goto ? :D Замени scope(exit) на goto clean: в функции PQExec, да или вообще просто чем вот это:
      ExpandedWrap disabled
            Result exec(...) {
              auto res = PQExec(...);
              scope(exit) PQClear(res);
              ...
              return Result(res);
            }
            
            auto res = exec(...);

      Отличается вот от этого:
      ExpandedWrap disabled
            Result exec(...) {
              auto res = PQExec(...);
              Result result(res);
         
              PQClear(res);
              ...
              return result;
            }
            
            auto res = exec(...);

      ???

      Цитата applegame @
      Возможно и появятся. Ты же нашел экспериментальныек scope в плюсах.

      Да потому что в плюсы тащат в последнее время то, что нафиг не уперлось, всякий шлак тупо.

      Цитата applegame @
      Тут похоже, ты один раз пишешь функцию-обертку, отлаживаешь ее (точно так же как и ты свою RAII-обертку) и используешь много раз не заботясь об освобождении ресурса.

      Чем это от Сишной какой нибудь функции отличается?

      Хорошо, вот есть у тебя файловый ресурс, покажи как ты это реализуешь? Открыть файл, почитать его, потом что то поделать с вычитанными данными, потом снова почитать, потом записать в него, потом почитать из него, потом закрыть его. Через запятую перечислены отдельные операции, каждая операция - отдельная функция. Потом все это нужно сделать в 10 различных местах.
      Покажи как мне это сделать со scope(exit)?

      Добавлено
      Цитата applegame @
      Но я привожу примеры, где scope(exit) проще и понятнее и не менее безопасно, чем RAII. Вы же мне в ответ приводите другие примеры, где RAII уместнее. Получается странный и бестолковый спор.

      Я тебе об этом писал еще раньше:
      Цитата Wound @
      Важно то, что тот контекст в котором ты говоришь, что якобы удобно писать scope(exit) вот тут - это удобно при твоей архитектуре приложения и удобно в том языке, в котором ты пишешь. Т.е. это не фича, что без нее вот тут будет плохо, это просто ты так написал свою программу. Я например напишу так, что в scope(exit) не будет никакого смысла, другой напишет так, что без goto не обойдешься.

      Все верно, ты просто выдумываешь примеры причем на D, где уместно будет юзнуть scope(exit), но в С++ - это же будет называться костылем. Тебе об этом как бы и пишут.

      Цитата applegame @
      Ну и наконец. Прошу все же учесть, что scope(...) это не только про RAII. scope это скорее про try/catch/finally. Вот коротенькая глава из книжки по D о скоупах, если интересно:

      Тото и оно, что все эти try/catch/finally - как раз и являются костылями в языках с GC, потому что там нельзя гарантировать вызов деструктора в определенное время и в определенном месте. Поэтому там просто без try/catch/finally - ты не сможешь нормально писать программу. Даже файл не закроешь нормально. А в С++ это нафиг не нужно, потому что там есть деструкторы.
      И об этом я тебе тоже писал:
      Цитата Wound @
      Это как знаешь, сказать в C#/Java есть ах**наая плюшка finally, а в С++ ее нет, бе бе бе. Вы мудохайтесь там теперь и живите с этим, а я finally юзаю и доволен. Ну как то вот так это выглядит
      Сообщение отредактировано: Wound -
        Цитата Wound @
        Ну как не правильная, я же говорю не про текущий пример, а вообще выкинь scope(exit) - его программа правильная, я имею ввиду что ему не нужно вызывать потом delete a; т.к. у него есть GC, соответственно он на него и положился.
        Ну напиши в scope(exit) вместо TTF_Quit(), witeln("Hello, world") и тоже все будет норм. Ты реально не понимаешь, что проблема вот в этом лишнем TTF_Quit(), а не в scope(exit)?
        Цитата Wound @
        Тут есть ошибки, если писать на D? В С++ в таком виде есть ошибка, а в D?
        В D нет ошибки, продолжай свою мысль.
        Цитата Wound @
        Т.е. по сути твой пример со scope(exit) ничем не отличается от того же goto ? :D Замени scope(exit) на goto clean: в функции PQExec, да или вообще просто чем вот это:
        ExpandedWrap disabled
              Result exec(...) {
                auto res = PQExec(...);
                scope(exit) PQClear(res);
                ...
                return Result(res);
              }
              
              auto res = exec(...);

        Отличается вот от этого:
        ExpandedWrap disabled
              Result exec(...) {
                auto res = PQExec(...);
                Result result(res);
           
                PQClear(res);
                ...
                return result;
              }
              
              auto res = exec(...);

        ???
        Тем, что во втором варианте, в случае возникновения исключения между auto res = PQExec(...) и PQClear(res), последний не будет вызван и получится утечка. А в первом PQClear(res) будет вызвн в любом случае. Может это то самое отличие от goto, о котором ты спрашиваешь?
        Цитата Wound @
        Да потому что в плюсы тащат в последнее время то, что нафиг не уперлось, всякий шлак тупо.
        Да в последнее время вообще придумывают всякий шлак вроде C#. :)
        Цитата Wound @
        Ну как не причем? Представь его бы не было. Как бы ты все это писал? Естественно на RAII каком нить, и у тебя такой ситуации просто не возникло бы.
        :facepalm: Ну давай я тебе напишу кривой аналог с RAII вместо scope(exit) с такими же сегфолтом:
        ExpandedWrap disabled
          struct TTFGuard {
              this() { TTF_Init(); }
              ~this() { TTF_Quit(); }
          }
           
          voiud main() {
              auto a = new SDL;
              TTFGuard guard;
          }

        Убери TTFGuard guard; И сегфолт пропадет. Прямо как со scope(exit). По-твоему, получается, что RAII опасно и его нужно использовать осторожно?
        Цитата Wound @
        Чем это от Сишной какой нибудь функции отличается?
        Я не понимаю что ты хочешь от меня услышать. scope(exit) и goto это совершенно разные вещи. goto - безусловный переход, scope вставляет указанный код в конец функции.
        Цитата Wound @
        Все верно, ты просто выдумываешь примеры причем на D, где уместно будет юзнуть scope(exit), но в С++ - это же будет называться костылем. Тебе об этом как бы и пишут.
        Во-первых, я не выдумываю, это реальные примеры. Во-вторых, scope(exit) в описываемых мной случаях был бы удобней и в C++, если бы он там был, конечно. Возможно скоро появится :), но все равно будет уродливым. Объявлять переменные, которые потом никак явно не используются в коде - какая гадость.
        Цитата Wound @
        Тото и оно, что все эти try/catch/finally - как раз и являются костылями в языках с GC, потому что там нельзя гарантировать вызов деструктора в определенное время и в определенном месте. Поэтому там просто без try/catch/finally - ты не сможешь нормально писать программу. Даже файл не закроешь нормально. А в С++ это нафиг не нужно, потому что там есть деструкторы.
        Ок, так и запишем, Киля считает что try и catch - это костыли для языков с GC и в C++ не нужны. Но на всякий случай, я уточню, ты наверное таки имел в виду только finally, а не try/catch/finally?
        Сообщение отредактировано: applegame -
          Цитата Wound @
          try/catch/finally - как раз и являются костылями в языках с GC

          Но в Delphi есть finally, но нет GC…
            Цитата Wound @
            Хорошо, вот есть у тебя файловый ресурс, покажи как ты это реализуешь? Открыть файл, почитать его, потом что то поделать с вычитанными данными, потом снова почитать, потом записать в него, потом почитать из него, потом закрыть его. Через запятую перечислены отдельные операции, каждая операция - отдельная функция. Потом все это нужно сделать в 10 различных местах.
            Покажи как мне это сделать со scope(exit)?
            "в 10 различных местах" - это в разных местах одной функции или что? Приведи лучше свой вариант с RAII (не обязательно c реально существующими названиями классов, можно гипотетически), а я приведу аналог со scope.

            Добавлено
            Цитата korvin @
            Но в Delphi есть finally, но нет GC…

            А в D, языке с GC, есть такие же гарантии как и в C++, но finally тоже есть. Правда я не видел, чтобы кто-то его использовал. :)
            Сообщение отредактировано: applegame -
              Цитата applegame @
              Ну напиши в scope(exit) вместо TTF_Quit(), witeln("Hello, world") и тоже все будет норм. Ты реально не понимаешь, что проблема вот в этом лишнем TTF_Quit(), а не в scope(exit)?

              :wacko: Ты точно читал что там на форуме обсуждалось?
              https://forum.dlang.org/post/kjkdfcnpgdegno...forum.dlang.org
              У него проблема не в лишнем TTF_Quit, у него проблема в порядке вызовов функций:
              Цитата

              I'm currently working on a project and for that I've created a thin OO-wrapper on top of derelict-sdl. However, when I close my app, the program terminates with a segfault. I've managed to track down the source, and found that the destructors of my objects are called AFTER the scope(exit) statements. This causes my program to call TTF_CloseFont() after TTF_Quit(), resulting in a segfault.

              Гугл перевод:
              В настоящее время я работаю над проектом, и для этого я создал тонкий OO-упаковщик поверх derelict-sdl. Однако когда я закрываю свое приложение, программа завершается с ошибкой. Мне удалось отследить источник, и обнаружил, что деструкторы моих объектов называются ПОСЛЕ scope(exit). Это заставляет мою программу вызывать TTF_CloseFont () после TTF_Quit (), в результате чего возникает ошибка.

              Он ожидает что у него отработает деструктор его класса De, в котором он вызывает TTF_CloseFont, а после него scope(exit) - который вызывает TTF_Quit. Но из за того что память под класс он выделил на хипе, у него вызывается сначало scope(exit) с TTF_Quit, а после отрабатывает деструктор класса De, в котором вызывается TTF_CloseFont. Где тут лишний вызов то?

              Цитата applegame @
              В D нет ошибки, продолжай свою мысль.

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


              Цитата applegame @
              Тем, что во втором варианте, в случае возникновения исключения между auto res = PQExec(...) и PQClear(res), последний не будет вызван и получится утечка. А в первом PQClear(res) будет вызвн в любом случае. Может это то самое отличие от goto, о котором ты спрашиваешь?

              Это же Си, там нет исключений! Если разница только в исключениях, то твоей пример ничем не отличается от сишного кода. А объяснять что подход с RAII лучше, чем Сишный нужно? Или ты и так знаешь?

              Цитата applegame @
              Да в последнее время вообще придумывают всякий шлак вроде C#.

              И чем же он плох? По моему очень даже хороший ЯП.

              Цитата applegame @
              :facepalm: Ну давай я тебе напишу кривой аналог с RAII вместо scope(exit) с такими же сегфолтом:

              Ага, багнутый аналог! В С++ там не пишут. Ты один ресурс в обертку обернул, а второй ресурс без обертки юзаешь. Здорово! :good:

              Цитата applegame @
              Убери TTFGuard guard; И сегфолт пропадет. Прямо как со scope(exit). По-твоему, получается, что RAII опасно и его нужно использовать осторожно?

              Ну хватит а? Хватит писать какую то муть. Ты если оборачиваешь в RAII - Оборачивай все. А то у тебя получается херня какая то. Я тоже могу написать какую нибудь неработающую херню на D и сказать - оцтой какойто, а не ЯП.

              Цитата applegame @
              Я не понимаю что ты хочешь от меня услышать. scope(exit) и goto это совершенно разные вещи. goto - безусловный переход, scope вставляет указанный код в конец функции.

              Ну а goto делает переход, например в конец функции. Ты представляешь этот scope(exit) - как какую то супер пупер фичу, на деле - это обычный костыль, судя по всему введен в язык исключительно с целью освобождения ресурсов при работе с GC. Это единственно верное его предназначение. Но ты выдаешь его зачем то за какую то конфетку :-?

              Цитата applegame @
              Во-первых, я не выдумываю, это реальные примеры. Во-вторых, scope(exit) в описываемых мной случаях был бы удобней и в C++, если бы он там был, конечно. Возможно скоро появится :), но все равно будет уродливым. Объявлять переменные, которые потом никак явно не используются в коде - какая гадость.

              В описываемых тобой случаях - там где он был бы удобен, он был бы удобен исключительно в качестве костыля.


              Цитата applegame @
              Ок, так и запишем, Киля считает что try и catch - это костыли для языков с GC и в C++ не нужны. И да, в D, языке с GC, такие гарантии есть, как и в C++.

              Не перевирай, я про try/catch - слова не сказал. Или ты не знаешь что такое try/catch/finally?


              Цитата applegame @
              Но на всякий случай, я уточню, ты наверное таки имел в виду только finally, а не try/catch/finally?

              Поясняю - я имел ввиду try/catch/finally, а не finally. На всякий случай посоветую тебе, ты прежде чем отвечать на это, загугли про это и почитай что такое finally и как оно используется в языках с GC JAVA/C#. Потом уже отвечай.
              Я не знаю как там в вашем D, но вообще конструкция try/catch/finally судя по всему родилась где то в Java, И вот этот finally - является не отъемлемой частью try/catch/finally, нельзя его написать без try/catch.
              Поэтому и называется она try/catch/finally. В C# есть аналогичная конструкция, но там быстро смекнули как этим херово было пользоваться в Java, и у себя сделали конструкцию using(var resource = new Resource()){}
              Которая по сути при выходе из блока вызывает Dispose, для освобождения ресурсов. В Java посоны плакали, кололись, но продолжали жрать кактус, пока потом в одной из последних версий не ввели свою конструкцию try-with-resources.

              Цитата korvin @
              Но в Delphi есть finally, но нет GC…

              Так в Delphi деструкторов потому что нет.

              Добавлено
              Цитата applegame @
              в 10 различных местах" - это в разных местах одной функции или что? Приведи лучше свой вариант с RAII (не обязательно c реально существующими названиями классов, можно гипотетически), а я приведу аналог со scope.

              Ну посмотри на класс std::fstream - обычная RAII Обертка над FILE* дескриптором. В 10 разных местах я хочу юзать вот эти функции, ну например у меня есть 10 кнопок, и в каждом обработчике я хочу производить вот примерно такие действия, разные и в разной последовательности, допустим в обработчике одной кнопки только читаем, во второй читаем и пишем, в третьей читаем, создаем новый файл в него пишем и т.д.. Т.е. мне нужны какие то функции или что ты там сделаешь, за которыми мне потом не надо подчищать, они же сами все сделают.

              Вообще не парься, у тебя не получится это сделать со scope(exit), либо получится говно какое то, в итоге ты просто напишешь RAII обертку. Что собственно и требовалось доказать.
              Сообщение отредактировано: Wound -
                Цитата Wound @
                Так в Delphi деструкторов потому что нет.

                Как это нет, когда есть?
                  Цитата korvin @
                  Как это нет, когда есть?

                  То что оно называется гордым словом destructor еще не означает что это аналог привычных плюсовых деструкторов. Уже ломали же копья по этому вопросу. В делфи есть инициализаторы и деинициализаторы. А вся модель конструктор/деструктор основана на некой фабрике объектов. Я тоже могу написать какое нибудь API на плюсах, и гдето там в базовом методе назвать метод Destructor, вместо Release, и че - это деструктором станет в привычном понимании этого слова?
                  Сообщение отредактировано: Wound -
                    Цитата Wound @
                    Он ожидает что у него отработает деструктор его класса De, в котором он вызывает TTF_CloseFont, а после него scope(exit) - который вызывает TTF_Quit. Но из за того что память под класс он выделил на хипе, у него вызывается сначало scope(exit) с TTF_Quit, а после отрабатывает деструктор класса De, в котором вызывается TTF_CloseFont. Где тут лишний вызов то?
                    Ты сам сказал, что если убрать совсем scope(exit), то программа станет корректной. А ведь в этом случае TTF_Quit не будт вызван вообще. Из твоих же слов следует, что вызов TTF_Quit лишний.
                    Чувак по незнанию неверно оценил ситуацию, он написал:
                    Цитата
                    AFTER the scope(exit) statements
                    А точнее было бы написать
                    Цитата
                    AFTER exit from the function scope
                    scope(exit) никак не влияет на порядок вызовов деструкторов объектов на куче.
                    Цитата Wound @
                    Вот именно. Поэтому ты без задней мысли будешь думать что ошибки у тебя нет. А в плюсах это баг априори. Соответственно ты ничего не будешь ждать, ты напишешь RAII обертку, и бага не будет.
                    Напиши scope(exit) delete(ptr) и бага не будет. По-твоему написать целую обертку гораздо проще, чем написать вот эту одну строчку, с учетом того что эта обертка будет использована ровно ОДИН раз?
                    Цитата Wound @
                    Это же Си, там нет исключений! Если разница только в исключениях, то твоей пример ничем не отличается от сишного кода. А объяснять что подход с RAII лучше, чем Сишный нужно? Или ты и так знаешь?
                    Очередной ошибочный вывод. Нет не только в исключениях. Также разница в ранних return, в том что код освобождения ресурса пишется прямо рядом с его захватом (прямо как твой любимый unique_ptr с кастомным деструктром, только гораздо опрятнее), ну и если таких мест несколько, то освобождение ресурсов будет выполнено автоматически в порядке обратном захвату. В сяшке ничего этого нет.
                    Цитата Wound @
                    Ага, багнутый аналог! В С++ там не пишут. Ты один ресурс в обертку обернул, а второй ресурс без обертки юзаешь. Здорово!
                    Ну так и пример багнутый. В D так не пишут. Чувак один ресурс обернул в scope(exit) а воторой доверил GC. Здорово!
                    Цитата Wound @
                    Ну хватит а? Хватит писать какую то муть. Ты если оборачиваешь в RAII - Оборачивай все. А то у тебя получается херня какая то.
                    Ну хватит а? Хватит писать какую то муть. Ты если оборачиваешь в scope(exit) - Оборачивай все. А то у тебя получается херня какая то.
                    Цитата Wound @
                    Я тоже могу написать какую нибудь неработающую херню на D и сказать - оцтой какойто, а не ЯП.
                    А ты примерно так и сделал. Притащил какую-то неработающую херню со scope(exit) и сказал - оцтой какойто.
                    Цитата Wound @
                    Ну а goto делает переход, например в конец функции. Ты представляешь этот scope(exit) - как какую то супер пупер фичу, на деле - это обычный костыль, судя по всему введен в язык исключительно с целью освобождения ресурсов при работе с GC. Это единственно верное его предназначение. Но ты выдаешь его зачем то за какую то конфетку
                    Неверно, scope(...) введен в язык для автоматического вызова кода при выходе из скоупа. А при работе с GC ресурсы обычно освобождаются самим GC. Накой там scope(...)?
                    Цитата Wound @
                    В описываемых тобой случаях - там где он был бы удобен, он был бы удобен исключительно в качестве костыля.
                    Вот годный пример использования scope(...). Нужно сделать подсчет текущих активных и успешных http-запросов в http-сервере:
                    ExpandedWrap disabled
                      auto handleHTTPRequest(...) {
                          activeRequests.atomicIncrement();
                          scope(exit) activeRequests.atomicDecrement();
                          scope(success) successRequests.atomicIncrement();
                          ...
                          if(...) return result1;
                          ...
                          if(...) throw Error1;
                          ...
                          if(...) return result2;
                          ...
                          if(...) throw Error2;
                          ...
                      }
                    И где тут костыль, даже если это написано на плюсах?
                    Цитата Wound @
                    Поясняю - я имел ввиду try/catch/finally, а не finally. На всякий случай посоветую тебе, ты прежде чем отвечать на это, загугли про это и почитай что такое finally и как оно используется в языках с GC JAVA/C#. Потом уже отвечай.
                    Я не знаю как там в вашем D, но вообще конструкция try/catch/finally судя по всему родилась где то в Java, И вот этот finally - является не отъемлемой частью try/catch/finally, нельзя его написать без try/catch.

                    Тебя трудно понять, Киля. Ты применяешь какие-то определения, выдавая их за общепринятые и потом тебя не понимают. Видимо ты имеешь в виду конструкцию, которую в C# называют try-catch-finally. Ну так ты опять ошибся, так как finally вполне можно написать без try-catch, а именно try-finally без catch.
                    Цитата Wound @
                    Ну посмотри на класс std::fstream - обычная RAII Обертка над FILE* дескриптором. В 10 разных местах я хочу юзать вот эти функции, ну например у меня есть 10 кнопок, и в каждом обработчике я хочу производить вот примерно такие действия, разные и в разной последовательности, допустим в обработчике одной кнопки только читаем, во второй читаем и пишем, в третьей читаем, создаем новый файл в него пишем и т.д.. Т.е. мне нужны какие то функции или что ты там сделаешь, за которыми мне потом не надо подчищать, они же сами все сделают.
                    В таком случае, да. RAII самое то.
                    Цитата Wound @
                    Вообще не парься, у тебя не получится это сделать со scope(exit), либо получится говно какое то, в итоге ты просто напишешь RAII обертку. Что собственно и требовалось доказать.
                    :lol: Ты привел пример, в котором RAII вполне уместен. Но я таки напишу специально для тебя все это дело в функциональном стиле без всякого RAII, но со scope(exit), дабы, так сказать, расширить твой и не только твой кругозор :)
                    ExpandedWrap disabled
                      // Это функция обертка, вместо RAII-объекта
                      void useFile(F fn)(string name, F fn) {
                          auto file = open(name);
                          scope(exit) close(file);
                          fn(file);
                      }
                       
                      void onClick(data) {
                          // используем обертку
                          useFile("hello.txt", (file) {
                              ...
                              write(file, data);
                              ...
                              data1 = read(file);
                              ...
                          });
                      }
                    Сообщение отредактировано: applegame -
                      Цитата applegame @
                      Ты сам сказал, что если убрать совсем scope(exit), то программа станет корректной. А ведь в этом случае TTF_Quit не будт вызван вообще. Из твоих же слов следует, что вызов TTF_Quit лишний.

                      Я тебе это говорил в контексте правильности/неправильности такого подхода на плюсах, чтоб обратить твое внимание на GC.

                      Цитата applegame @
                      Чувак по незнанию неверно оценил ситуацию, он написал:
                      Цитата
                      AFTER the scope(exit) statements
                      А точнее было бы написать
                      Цитата
                      AFTER exit from the function scope
                      scope(exit) никак не влияет на порядок вызовов деструкторов объектов на куче.

                      Он как раз все верно оценил, если я правильно понял что там произошло. Ты же видишь в его примере просто надпись в консоль выводится? У него вывелось:
                      ExpandedWrap disabled
                        scope exit
                        De
                        De

                      А произошло это из за того, что после выхода из функции - не отработал деструктор De, который написан перед scope(exit), этот деструктор отработал в тот момент, когда GC начал подчищать ресурсы, а ресурсы в его случае он начал подчищать, когда он нажал на кнопку Закрыть.

                      сам по себе scope(exit) - Не влияет на порядок вызовов деструкторов, я нигде не утверждал что он влияет. Но используя этот scope(exit) - можно нарваться вот на такие грабли, как у чувака, вот об этом я и написал.

                      Цитата applegame @
                      Напиши scope(exit) delete(ptr) и бага не будет. По-твоему написать целую обертку гораздо проще, чем написать вот эту одну строчку, с учетом того что эта обертка будет использована ровно ОДИН раз?

                      Ну да, нахер юзать все эти RAII в плюсах. Вот дебилы, правда? че сложно написать delete ptr - где это нужно.
                      По моему, обертку писать не нужно вообще. Это ты придумал. Я предлагал юзать unique_ptr, если тебе хочется сделать вот именно так, а никак иначе.

                      Цитата applegame @
                      Очередной ошибочный вывод. Нет не только в исключениях. Также разница в ранних return, в том что код освобождения ресурса пишется прямо рядом с его захватом (прямо как твой любимый unique_ptr с кастомным деструктром, только гораздо опрятнее), ну и если таких мест несколько, то освобождение ресурсов будет выполнено автоматически в порядке обратном захвату. В сяшке ничего этого нет.

                      В Сяшке ровно тот же механизм, только вид с боку. Когда ты юзаешь мой любимый unique_ptr, то это полноценная RAII обертка, и она лишена практически всех недостатков. Например что будет у тебя, если во время выделения ресурса произойдет исключение? Будет очищать ресурс, который не существует?

                      Цитата applegame @
                      Ну так и пример багнутый. В D так не пишут. Чувак один ресурс обернул в scope(exit) а воторой доверил GC. Здорово!

                      Ну как не пишут, если пишут? Я ж даже ссылку привел на того, кто написал :-?

                      Цитата applegame @
                      А ты примерно так и сделал. Притащил какую-то неработающую херню со scope(exit) и сказал - оцтой какойто.

                      Ага, с тебя взял пример. Ты же первый начал рассказывать как без него тяжко в плюсах жить :D

                      Цитата applegame @
                      Неверно, scope(...) введен в язык для автоматического вызова кода при выходе из скоупа. А при работе с GC ресурсы обычно освобождаются самим GC. Накой там scope(...)?

                      На той же на кой finally в языках с GC существует. Расскажи, как ты закроешь сетевое соединение например по выходу из функции, если объект создается на куче? Да ты же бля напишешь scope(exit), ты уже приводил даже этот пример с PQExec :D

                      Цитата applegame @
                      И где тут костыль, даже если это написано на плюсах?

                      Понятия не имею по этому коду ничего не очевидно.

                      Цитата applegame @
                      Тебя трудно понять, Киля. Ты применяешь какие-то определения, выдавая их за общепринятые и потом тебя не понимают. Видимо ты имеешь в виду конструкцию, которую в C# называют try-catch-finally. Ну так ты опять ошибся, так как finally вполне можно написать без try-catch, а именно try-finally без catch.

                      Ты как раз таки все понял, просто тебе видимо потроллить хочеца. Я слышал в Java его частенько называют именно так. И название идет от полной конструкции. Finally не фигурирует сам по себе. Так что ты тоже ошибся выходит, если цеплятся к словам, как ты любишь ;)

                      Цитата applegame @
                      Ты привел пример, в котором RAII вполне уместен. Но я таки напишу специально для тебя все это дело в функциональном стиле без всякого RAII, но со scope(exit), дабы, так сказать, расширить твой и не только твой кругозор

                      Угумс, я уже видел похожее на шарпах, когда двухсотстрочная портянка оформлена в подобном виде! Очень удобно :good:
                      Там это к слову очень сильно распространено. Делегаты называется.
                      Сообщение отредактировано: Wound -
                        Цитата applegame @
                        А при работе с GC ресурсы обычно освобождаются самим GC.

                        Обычно — нет. А финализаторы в Java давно признаны слишком проблемными. Поэтому ресурсы нужно использовать с try-with-resources.
                          Цитата applegame @
                          Конечно. RAII - это прекрасная технология, особенно если нужен именно объект владеющий ресурсом.

                          А ты разве не такой пример привел?

                          Цитата
                          А вот в случае когда нужен скоуп владеющий ресурсом, RAII зачастую совершенно излишен.

                          Не согласен, он все равно лучше, чем явный defer/scope(exit).
                          Классический пример скоупа - блокировка.
                          Сравни:
                          ExpandedWrap disabled
                            std::lock_guard lock(mtx);

                          И
                          ExpandedWrap disabled
                            mtx.lock();
                            scope(exit) mtx.unlock();


                          Цитата
                          Угадай, как функциональщики без всяких RAII управляют, допустим, транзакциями в БД? :)

                          Транзакции не делал, а для управления ресурсами используется bracket pattern в том же haskell:
                          ExpandedWrap disabled
                            main = do    
                                withFile "foo.txt" ReadMode (\handle -> do  
                                    ...)


                          И это как раз то, о чем я говорю.

                          Цитата
                          В таком случае вероятность забывания написания scope равна вероятности забывания написания деструктора. :)

                          Верно. И к этому примеру никаких претензий, это аналог RAII, хотя и с ограничениями.
                          Но ты привел не этот код ;)

                          Именно так сделано в Ruby и Kotlin, например. Да и bracket pattern о том же, по сути.

                          Добавлено
                          Цитата applegame @
                          Но я привожу примеры, где scope(exit) проще и понятнее и не менее безопасно, чем RAII.

                          Пока у тебя не получилось :)

                          Цитата
                          scope это скорее про try/catch/finally.

                          Можно согласиться, что defer/scope(exit) лучше finally(хотя и не сильно).
                          Но еще лучше using/with/try-with-resources. Тем, что не нужно каждый раз указывать действие по освобождению.
                          На том же уровне with*-функции. ИМХО, их сложнее "забыть" использовать плюс они реализуются без изменения языка(как и RAII), что тоже плюс.
                          Но RAII выигрывает и у них. Хотя бы тем, что может быть точно так же использован для полей структуры/класса.
                            Цитата Wound @
                            В среднем fread быстрее.
                            Я бы не стал доверять программе, написанной в нарушение Стандарта и неверно считающей оверхед. Совсем не верно. Вообще.
                              Цитата JoeUser @
                              А что не так с Delphi?
                              Дык он тоже весь на finally. Там практически ничего без SEH написать невозможно, течь будет из всех щелей контрактов. Посмотри на нормальные Плюсовые сырцы: catch редки, а если и встречаются, то внутри реализаций.
                              Цитата applegame @
                              А зачем так писать? Заворачиваем в функцию и вызываем сколько угодно раз не парясь об освобождении ресурса
                              И чем это будет отличаться от классического RAII? Ты ещё не забыл о главном преимуществе scope()ов, за которое радеешь?
                              Цитата applegame @
                              А вот в случае когда нужен скоуп владеющий ресурсом, RAII зачастую совершенно излишен.
                              Вот. Собственно это и есть тот критерий, который оправдано можно закостылить scope()ом... но вдруг и внезапно – скоуп может захотеть владеть разными ресурсами, в разном количестве и с разной стратегией владения. Ну и получите и распишитесь, получили такой маленький упсик. Собственно, всё равно владельцем выступает программист, а скоуп просто выступает в роли послушного исполнителя твоей воли. Ибо дашь ему неверные инструкции, он и исполнит их неверно, а давать приходится постоянно, пусть и одни и те же. В RAII инструкции даются один раз, и они всегда одинаковые. Может быть иногда и не удобно, но всегда надёжно.

                              Добавлено
                              Цитата applegame @
                              Ну так в моем случае оно тоже автоматическое.
                              Не путай с автоматическим контролем и исполнением инвариантов. Исполнение данных тобой инструкций – да, автоматическое. С этим и __attribute__((__cleanup__())) справляется. Интересно, почему его не включали в Стандарт C? Это же так удобно, по твоим словам.
                                Цитата Qraizer @
                                Я бы не стал доверять программе, написанной в нарушение Стандарта и неверно считающей оверхед. Совсем не верно. Вообще.
                                Чтобы далеко не посылать.
                                Первые два load-а читают посимвольно из-за того, что не знают, сколько там данных. Это также вызывает постоянные реаллокации приёмного буфера. Вторые два load-а читают скопом весь файл, заранее сконфигурировав приёмный буфер на требуемый размер. Что-то это мне напоминает... Ах да, std::vector<T> vs T*. Ну разве не прелесть.

                                Добавлено
                                Быстренько налобал правильный тест. Теперь все load-ы читают посимвольно в буфер достаточного размера. Полюбуйтесь:
                                ExpandedWrap disabled
                                  File test1.fil
                                  C++ istreambuf_iterator       : ..........       6906 us
                                  C++ stream::rdbuf             : ..........       7737 us (0.89)
                                  libc fread                    : ..........      33049 us (0.21)
                                  POSIX read                    : ..........    2367907 us (0.00)
                                  File test2.fil
                                  C++ istreambuf_iterator       : ..........      13458 us
                                  C++ stream::rdbuf             : ..........      15141 us (0.89)
                                  libc fread                    : ..........      64100 us (0.21)
                                  POSIX read                    : ..........    4671184 us (0.00)
                                  File test4.fil
                                  C++ istreambuf_iterator       : ..........      29175 us
                                  C++ stream::rdbuf             : ..........      32303 us (0.90)
                                  libc fread                    : ..........     133641 us (0.22)
                                  POSIX read                    : ..........    9758374 us (0.00)
                                  File test8.fil
                                  C++ istreambuf_iterator       : ..........      60140 us
                                  C++ stream::rdbuf             : ..........      65874 us (0.91)
                                  libc fread                    : ..........     267079 us (0.23)
                                  POSIX read                    : ..........   19191693 us (0.00)
                                  File test16.fil
                                  C++ istreambuf_iterator       : ..........     117328 us
                                  C++ stream::rdbuf             : ..........     130321 us (0.90)
                                  libc fread                    : ..........     547789 us (0.21)
                                  POSIX read                    : ..........   38444935 us (0.00)
                                  File test32.fil
                                  C++ istreambuf_iterator       : ..........     243340 us
                                  C++ stream::rdbuf             : ..........     265980 us (0.91)
                                  libc fread                    : ..........    1090477 us (0.22)
                                  POSIX read                    : ..........   75824446 us (0.00)
                                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                0 пользователей:
                                Страницы: (32) « Первая ... 25 26 [27] 28 29 ...  31 32


                                Рейтинг@Mail.ru
                                [ Script execution time: 0,1052 ]   [ 15 queries used ]   [ Generated: 7.05.24, 17:30 GMT ]