На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! Правила раздела:
1. Название темы - краткое описание кто/что против кого/чего
2. В первом сообщении - список параметров, по которым идет сравнение.
3. Старайтесь аргументировать свои высказывания. Фразы типа "Венда/Слюникс - ацтой" считаются флудом.
4. Давайте жить дружно и не доводить обсуждение до маразма и личных оскорблений.
Модераторы: Модераторы, Комодераторы
Страницы: (32) « Первая ... 24 25 [26] 27 28 ...  31 32  ( Перейти к последнему сообщению )  
> goto vs break & continue , Кроха-сын пришел к отцу и спросила кроха: "goto - это хорошо?"
    Цитата Qraizer @
    Ну и да, контракты тоже можно описать с ошибками, это не абсолютная панацея.

    Или вообще не описывать =)

    https://youtu.be/IiGXq3yY70o?t=782
      Цитата Wound @
      На крайняк можно юзнуть деструктор смарт поинтера

      Так норм? ;)

      ExpandedWrap disabled
        #include <fcntl.h>
        #include <sys/stat.h>
         
        bool ReadFile(std::string iFileName, std::string *iContent) {
          auto close_file = [](int *iFp) {
            close(*iFp);
          };
          auto Fp = std::unique_ptr<int, decltype(close_file)> (
                                    new int(open(iFileName.c_str(), O_RDONLY)),
                                    close_file);
          int Fd = *Fp.get();
          if (Fd < 0) return false;
          struct stat Sb;
          if (fstat(Fd, &Sb) < 0) return false;
          iContent->resize(Sb.st_size);
          if (read(Fd, const_cast<char *>(iContent->data()), Sb.st_size) < 0) return false;
          return true;
        }
        Цитата JoeUser @
        Так норм?

        А чем тебя std::ifstream не устроил? :huh: std::unique_ptr - с указателями работает, я бы на крайняк взял уже FILE* fopen/fclose.
        А так у тебя костыль какой то + утечка памяти(под int* память выделил, а не освободил).

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

        Добавлено
        Уж лучше как то так переписать тогда:
        ExpandedWrap disabled
            auto close_file = [](FILE* pFile) {
              fclose(pFile);
            };
            auto Fp = std::unique_ptr<FILE, decltype(close_file)> (fopen(iFileName.c_str(), O_RDONLY),close_file);

        Но вообще судя по std::string, я бы юзал std::ifstream.
          Цитата Wound @
          А чем тебя std::ifstream не устроил?

          Тормозючий.

          Цитата Wound @
          А так у тебя костыль какой то + утечка памяти(под int* память выделил, а не освободил).

          А еcли так?

          ExpandedWrap disabled
            #include <fcntl.h>
            #include <sys/stat.h>
             
            bool ReadFile(std::string iFileName, std::string *iContent) {
              auto close_file = [](int *iFp) {
                close(*iFp);
                delete iFp;
              };
              auto Fp = std::unique_ptr<int, decltype(close_file)> (
                                        new int(open(iFileName.c_str(), O_RDONLY)),
                                        close_file);
              int Fd = *Fp.get();
              if (Fd < 0) return false;
              struct stat Sb;
              if (fstat(Fd, &Sb) < 0) return false;
              iContent->resize(Sb.st_size);
              if (read(Fd, const_cast<char *>(iContent->data()), Sb.st_size) < 0) return false;
              return true;
            }
            Цитата JoeUser @
            Тормозючий.

            Ок, FILE* fopen/fclose - чем не угодил?

            Цитата JoeUser @
            А еcли так?

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

            Добавлено
            Нет, оно так конечно будет работать, и все по принципу RAII - но меня лично смущает что ты по факту выделяешь 2 ресурса в одной обертке.
            Сообщение отредактировано: Wound -
              Цитата Wound @
              Ок, FILE* fopen/fclose - чем не угодил?

              Не такой тормозючий как std::ifstream, но чуть медленнее POSIX варианта. Я не про открытие, а про read/write.

              Цитата Wound @
              Да костыль это. Ты делаешь какое то левое телодвижение для того, чтоб у тебя скомпилировалось. Это не айс.

              Ну нужен мне open, что тут поделать?
                Цитата JoeUser @
                Ну нужен мне open, что тут поделать?

                Пиши класс обертку тогда. Так будет правильнее. Либо, можно посмотреть какую нить фичу в С++, которая конвертирует тип в указатель.

                    В среднем fread быстрее.

                    Добавлено
                    Вообще они одинаковы. Видно же. А то что там на пару милисикунд где то POSIX Обогнал - это скорее всего от функций вообще не зависит, винт подзадумался небось вот и разница.
                      Цитата Wound @
                      В среднем fread быстрее.

                      Не, в 4-x из 18 тестов - быстрее. А в остальных 14 - проигрывает.

                      Добавлено
                      Цитата Wound @
                      Нет, оно так конечно будет работать, и все по принципу RAII

                      Все равно выше у меня было неправильно :lol: Вот теперь должно быть правильно:

                      ExpandedWrap disabled
                        #include <fcntl.h>
                        #include <sys/stat.h>
                         
                        bool ReadFile(std::string iFileName, std::string *iContent) {
                          auto close_file = [](int *iFp) {
                            if (*iFp>=0) close(*iFp);
                            delete iFp;
                          };
                          auto Fp = std::unique_ptr<int, decltype(close_file)> (
                                                    new int(open(iFileName.c_str(), O_RDONLY)),
                                                    close_file);
                          int Fd = *Fp.get();
                          if (Fd < 0) return false;
                          struct stat Sb;
                          if (fstat(Fd, &Sb) < 0) return false;
                          iContent->resize(Sb.st_size);
                          if (read(Fd, const_cast<char *>(iContent->data()), Sb.st_size) < 0) return false;
                          return true;
                        }
                        Цитата Qraizer @
                        Чё-то я в этом списке Delphi не вижу. Непорядок?
                        Там написано "и прочее", куда вполне может входить и Delphi. Невнимательность? Впрочем, ты прав, в мое "и прочее" Delphi не входит, но когда-то очень давно туда входил его брат C++ Builder. А что не так с Delphi? :)
                        Цитата Qraizer @
                        Это прекрасно, пока не встретишь
                        ExpandedWrap disabled
                          auto res1 = PQExec(...);
                          scope(exit) PQClear(res1);
                          auto res2 = PQExec(...);
                          scope(exit) PQClear(res1);
                          auto res3 = PQExec(...);
                          scope(exit) PQClear(res1);
                        А зачем так писать? Заворачиваем в функцию и вызываем сколько угодно раз не парясь об освобождении ресурса. Смотри ответ Дикею ниже.
                        Цитата D_KEY @
                        Я тоже пробовал много чего, в том числе и то, что указал ты (кроме elixir, да и D мало слишком).
                        Я не считаю C++ лучшим или что-то такое, но вот RAII очень крутая (и при этом простая) концепция.
                        Конечно. RAII - это прекрасная технология, особенно если нужен именно объект владеющий ресурсом. А вот в случае когда нужен скоуп владеющий ресурсом, RAII зачастую совершенно излишен. Ты, видимо, совсем мало использовал ФП иначе знал бы об этом. Угадай, как функциональщики без всяких RAII управляют, допустим, транзакциями в БД? :)
                        Цитата D_KEY @
                        Ага, это пока в очередной раз фигача подобный код ты не забудешь воткнуть свой scope(exit). Нафиг.
                        Владелец пишется один раз (благодаря умным указателям это иногда просто typedef/using), используется потом много где просто как:
                        ExpandedWrap disabled
                          auto res = PQExec(...);

                        Сравнивай.
                        :D Инерция мышления, однако. Очевидно, если захват и освобождение ресурса необходимо повторить много раз, пишется обертка, только не класс, а функция, которая нередко (но не всегда) оказывается проще и понятнее RAII аналога:
                        ExpandedWrap disabled
                          Result exec(...) {
                            auto res = PQExec(...);
                            scope(exit) PQClear(res);
                            ...
                            return Result(res);
                          }
                           
                          auto res = exec(...);

                        Сравнивай. :lol:
                        В таком случае вероятность забывания написания scope равна вероятности забывания написания деструктора. :)
                        Цитата D_KEY @
                        ООП не имеет никакого отношения к теме. Совсем.
                        Я бы даже сказал, что без GC нормального ООП быть не может, но чистые плюсовики меня растерзают, поэтому я не стану этого говорить
                        Обертку во многих случаях даже писать не придется - есть unique_ptr и shared_ptr. Напишешь один using и вперед.
                        Сам по себе ООП нет, а вот образ мышления, который навязывает мейнстримовый ООП (который на трех китах) очень даже имеет. Ну и не забываем, что scope() может рулить чем угодно, например, теми же транзакциями в БД или мьютексами, а всякие xxxx_ptr только указателями.
                        Цитата Wound @
                        Я же ссылку привел выше, ок продублирую еще раз:
                        https://forum.dlang.org/thread/kjkdfcnpgdeg...forum.dlang.org

                        Вот тут чувак выхватил сигфолт благодаря GC и scope(exit).
                        Прочитал. scope(exit) там не причем. С тем же успехом можно сегфолтнуть и в деструкторе RAII обертки. Чувак просто не знал, что в D (как и в Java и, наверное, в C#, поправь если не так) объекты на куче автоматически не дестроятся при выходе из скоупа, так как этим занимается GC. А вот объекты на стеке дестроятся автоматически как и в C++.
                        Сообщение отредактировано: applegame -
                          Цитата applegame @
                          Прочитал. scope(exit) там не причем. С тем же успехом можно сегфолтнуть и в деструкторе RAII обертки. Чувак просто не знал, что в D (как и в Java и, наверное, в C#, поправь если не так) объекты на куче автоматически не дестроятся при выходе из скоупа, так как этим занимается GC. А вот объекты на стеке дестроятся автоматически как и в C++.

                          Нет, не с тем же успехом. Если убрать его багу, допустим выкинуть scope(exit) вообще из его программы, никаких сигфолтов нет. Его программа абсолютна правильная и рабочая на языке D.
                          Но не в С++, вот в этом и состоит существенная разница. Для С++ эта программа багнутая. Поэтому в D - ты можешь выхватить очень просто этот сигфолт, потому что тебе нужно этот ньюанс держать в голове.
                          А в С++, если следовать всем правилам - такой ситуации просто не получится. Потому что раз там указатель и память выделяется по new, значит это так же оборачивается в RAII обертку. А она сама знает когда нужно вызвать деструктор.

                          Ну я не знаю с чем ты споришь. В Dшном примере - ручное управление ресурсом в перемешку с автоматическим GC. В С++ если это все обернуть в RAII обертки - полностью автоматическое управление ресурсом.

                          Добавлено
                          Если я неясно выразился, поясню на примере:
                          Возьмем вариант D. Было:
                          ExpandedWrap disabled
                            import std.stdio;
                             
                            struct De
                            {
                                ~this() { writeln("De"); }
                            }
                             
                            void main()
                            {
                                De a;
                                scope(exit) writeln("scope exit");
                                De b;
                            }

                          Все работало правильно.
                          Потом пришел Вася, и с бодуна поправил какой то баг:
                          ExpandedWrap disabled
                            import std.stdio;
                             
                            struct De
                            {
                                ~this() { writeln("De"); }
                            }
                             
                            void main()
                            {
                                auto a = new De();
                                scope(exit) writeln("scope exit");
                                De b;
                            }

                          И опля - породил еще один баг. Вася просто не увидел scope(exit), думал о другом, еще что то там.
                          А в С++ если вася так исправит - это не пройдет код ревью, либо он заведомо напишет баг, память по new выделил, а удалить то забыл, тю тю. А если вася грамотный, он естественно будет писать RAII обертки, и у него такой ситуации просто не возникнет.
                            Цитата Wound @
                            Ручное управление ресурсом - всегда хуже автоматического, потому как является источником многих косяков и багов.
                            Ну так в моем случае оно тоже автоматическое. Точнее, я только в одном месте использую scope, а далее просто вызываю функцию. Точно так же ты, делая обертку в дуструкторе вручную освобождаешь ресурсы. Вопрос исключительно в простоте, понятности и читабельности. В C++ у тебя особо-то и выбора нет, в отличие от того же D, где ты можешь использовать и RAII и scope(exit) в зависимости от ситуации. С появлением в плюсах лямбд стало несколько попроще, некоторые плюсовики даже внезапно открыли для себя ФП техники давно применяющиеся в том же D :lol:. Но лямбды в плюсах, как и все остальное, получились страшными, как атомная война. Поэтому, видимо, с таким скрипом и удивлением люди узнают, что помимо их любимых, казавшихся единственными и самыми правильными техниками, существуют и другие более простые, понятные и не менее безопасные техники.
                            Цитата Qraizer @
                            Так что scope-ы всё равно остаются и навсегда останутся костылями.
                            Как я тебя понимаю, сам таким был несколько лет назад. :D
                              Цитата Wound @
                              Пиши класс обертку тогда.

                              В принципе, я помню пост Qraizer'а. Но мне кажется, что по накладным расходам они очень близки. Но у него Guard на стеке. Поэтому переделываем еще, чтобы быть не хуже :lol:

                              ExpandedWrap disabled
                                bool ReadFile(std::string iFileName, std::string *iContent) {
                                  int Place;
                                  auto close_file = [](int *iFp) {
                                    if (*iFp >= 0) close(*iFp);
                                  };
                                  auto Fp = std::unique_ptr<int, decltype(close_file)> (
                                              new (&Place) int(open(iFileName.c_str(), O_RDONLY)),
                                              close_file);
                                  int Fd = *Fp.get();
                                  if (Fd < 0) return false;
                                  struct stat Sb;
                                  if (fstat(Fd, &Sb) < 0) return false;
                                  iContent->resize(Sb.st_size);
                                  if (read(Fd, const_cast<char *>(iContent->data()), Sb.st_size) < 0) return false;
                                  return true;
                                }


                              И утечки нет, и все на стеке сидит (за исключением хитрого указателя, у него кишки небойсь в куче?). :victory:
                                Цитата applegame @
                                Ну так в моем случае оно тоже автоматическое. Точнее, я только в одном месте использую scope, а далее просто вызываю функцию. Точно так же ты, делая обертку в дуструкторе вручную освобождаешь ресурсы. Вопрос исключительно в простоте, понятности и читабельности. В C++ у тебя особо-то и выбора нет, в отличие от того же D, где ты можешь использовать и RAII и scope(exit) в зависимости от ситуации. С появлением в плюсах лямбд стало несколько попроще, некоторые плюсовики даже внезапно открыли для себя ФП техники давно применяющиеся в том же D :lol:. Но лямбды в плюсах, как и все остальное, получились страшными, как атомная война. Поэтому, видимо, с таким скрипом и удивлением люди узнают, что помимо их любимых, казавшихся единственными и самыми правильными техниками, существуют и другие более простые, понятные и не менее безопасные техники.

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

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

                                Я думаю, что если бы этот scope(exit) был таким же крутым как RAII, то во всяких Java/C# он давно бы уже был, вместо этих ваших using/try-with-resources, которые имитируют как раз RAII, с принудительным вызовом деструктора.

                                Добавлено
                                Потому что как показывает практика, выделять ресурс никто не забывает в основном, забывают написать освобождение ресурса, либо делают его не в том порядке, либо сама программа спроектирована так, что вызывает эти функции очистки не в том порядке, что приводит к ошибкам. Конечно - когда ты тут показываешь 3 строчки кода - тут все красиво и понятно, а когда есть большой проект, то становится все не так очевидно.
                                В случае с RAII ты пишешь инициализацию/удаление отдельно, и забыть написать удаление - конечно можно, но это довольно не тривиальная задача. А потом просто юзай и все, не заботясь о том в каком там порядке что у тебя вызывается, или когда там нужно очистить если исключение произошло или еще что то, сам компилятор за тебя все очистит правильно и гарантированно в нужном порядке.
                                Сообщение отредактировано: Wound -
                                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                0 пользователей:
                                Страницы: (32) « Первая ... 24 25 [26] 27 28 ...  31 32


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