1. C++ / Говнокод #17731

    +62

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    void f(bool *ok = 0)
    {
        //тут возникла ошибка
        if (ok)
            *ok = false;
        return;
    }
    
    //далее в коде
    bool ok = false;
    f(&ok);

    не, ну заебок, чо

    Запостил: blackhearted, 05 Марта 2015

    Комментарии (85) RSS

    • какие возможности открываются:

      void f(bool *ok = 0, bool *ok_2 = 0, bool *ok_c = 0, bool *okok = 0, bool *ohreally = 0)
      Ответить
    • &gk17731
      http://habrahabr.ru/post/252215/#comment_8314039
      Ответить
    • Долой исключения! Даешь хардкорные указатели!!!
      Ответить
    • bool *ok = nullptr

      fixed
      Ответить
    • Такое решение в Qt видел.
      Ответить
    • Практически АОП.
      Ответить
    • Оно в true выставляется хоть где-то?
      Ответить
    • Съешь еще этих мягких французских boolok...
      Ответить
    • Мне для обработки ошибок нравится православный Either, для крестов Александреску переизобрёл вот такое его воплощение
      http://channel9.msdn.com/Shows/Going+Deep/C-and-Beyond-2012-Andrei-Alexandrescu-Systematic-Error-Handling-in-C
      Код у александрески слегка косячный (да, даже александреску косячит, когда пишет на крестах), но идея весьма неплохая.
      Ответить
      • Блин, 1.5 часа видео. А нету текстового описания идеи?
        Ответить
        • Слайды
          http://tinyurl.com/alexandrescu-expected
          Ответить
          • Спасибо, вечером гляну.
            Ответить
          • Забавно - Александреску привёл в пример Maybe из хаскеля и само-собой обосрал его за то, что исключение в него не положить. А про Either скромно умолчал :)
            Ответить
            • Да, меня тоже порадовал этот хитрый маркетинговый ход.
              Ответить
              • Да ещё и читерская реализация через union. Хотя, согласен, реальную реализацию optional'а на коленке не накидать и на одном слайде не показать.
                Ответить
                • Почему читерская? В c++11 она, кажется, вполне адекватна.
                  Ответить
                  • Ой. А я и не думал, что в c++11 можно и нетривиальную фигню в юнион засунуть. Годная фича. Можно подразнить Тараса.
                    Ответить
            • Расскажите что там, вкратце суть идеи, а то MS Word даже в онлайне говно - у меня ничё не показует.
              Ответить
              • Either из хаски
                Ответить
                • Бля, ну вот я много понял, да. Тем более что борманд выше его уже упоминал.
                  Я-то домыслил что метаданные разных типов заворачиваются, при успехе/ошибке, и какой профит с этого?
                  Ответить
                  • В переводе на жабу что-то вроде этого:
                    public class Expected<T> {
                        private RuntimeException error;
                        private T value;
                    
                        private Expected() {}
                    
                        public static <T> Expected<T> fromValue(T value) {
                            if (value == null) {
                                throw new IllegalArgumentException("Value must not be null");
                            }
                            Expected<T> result = new Expected<T>();
                            result.value = value;
                            return result;
                        }
                    
                        public static <T> Expected<T> fromException(RuntimeException error) {
                            if (error == null) {
                                throw new IllegalArgumentException("Error must not be null");
                            }
                            Expected<T> result = new Expected<T>();
                            result.error = error;
                            return result;
                        }
                    
                        public boolean valid() {
                            return value != null;
                        }
                    
                        public T get() {
                            if (!valid()) {
                                throw error;
                            }
                            return value;
                        }
                    }
                    Суть в том, что так можно возвращать детальный отчёт об ошибке без выбрасывания исключений. Один из наших юзкейсов - есть файл с последовательностью сериализованных объектов. Хочется распарсить максимально возможное кол-во объектов. Идея в том, чтобы кидать только на откровенно кривых данных, а ошибки валидации отдельных объектов заворачивать в такие вот ящики пандоры. Примерная сигнатура десериализатора
                    List<Expected<Model>> parseAll(Stream)
                    Ответить
                    • Спасибо. Ну я в целом так и подумал (про эксцепшены). Этой идее уже лет и лет. Но в описании Either меня смутили какие-то Left и Right.
                      >Expected
                      >public T get() {
                      А не напоминает ли Вам эта конструкция FutureTask?

                      А еще за юнион "что в c++11 можно и нетривиальную фигню в юнион засунуть. Годная фича" если не трудно поясните.
                      Ответить
                      • > А не напоминает ли Вам эта конструкция FutureTask?
                        Александреску так и сказал на конференции, что это в точности фьючерс, только синхронный и супер простой. Соответственно, работает в разы быстрее (говорит, раз в 10 насчитали).

                        > если не трудно поясните
                        До C++11 нельзя было в юнион класть объекты с нетривиальными конструкторами-деструкторами (не POD-ы). Теперь можно, но хранить теги типов и вызывать конструкторы-деструкторы извольте сами.
                        Ответить
                        • >Соответственно, работает в разы быстрее (говорит, раз в 10 насчитали)
                          Дык оверхеда на свитч потоков нету, конечно, и в кернеле время не тратится.

                          >До C++11 нельзя было в юнион класть объекты с нетривиальными конструкторами-деструкторами
                          Хренасе. Ну я понял в общем-то. Сишка — нет RAII, нет проблем.
                          Ответить
                        • Я не понял: нафига тип юзингом из неймспейса доставать перед тем как его уничтожить? какая может быть ошибка иначе?
                          Ответить
                          • Готов поспорить достаточно typedef если spam.~std::exception_ptr не компилируется из-за ::
                            Ответить
                            • на самом деле достаточно написать просто spam.~exception_ptr(); без всяких юзингов и тайпдефов.
                              Ответить
                              • Я смотрю он свой скоп_гуард доработал до поддержки комита транзакции.

                                А не знать о Эйзе из хаскеля - это глупо с его стороны
                                Ответить
          • Я вычислил тебя по вандрайву
            Ответить
            • А ты уверен, что это Романовский one-drive?
              Ответить
              • Ну а кто ещё редистрибьютит, когда написано:
                > Do not redistribute.
                Это все равно что:
                Loki::Expected<std::exception>
                Ответить
                • > написано Do not redistribute
                  Кто-то когда-то соблюдал эти просьбы?
                  Ответить
            • я не пользуюсь вандрайвом, только гуглодиском и я.диском.
              Ответить
      • >>да, даже александреску косячит, когда пишет на крестах

        и только человек-стол и лисп неделимы
        Ответить
      • А где он накосячил?
        Ответить
        • Вот, например, кусок:
          auto t = std::move(rhs.spam);
          new(&rhs.ham)T(std::move(ham));
          new(&spam)std::exception_ptr(t);
          std::swap(gotHam,rhs.gotHam);
          Тут он забыл вызвать деструктор ham перед тем, как записать t в spam. Если у нас объект не умеет в перемещение (только в копирование), то будет утечка ресурсов. Ну и деструктрор exception_ptr в rhs.ham для порядку тоже вызвать надо.

          Далее придирки: объект поддерживает перемещение, но не имеет конструктора по-умолчанию. Т.е. есть состояние объекта, которое можно получить только перемещением. Кажется, это довольно странно - гораздо логичнее сделать замувленный объект эквивалентным сконструированному по-умолчанию.
          Ответить
          • Он там даже лямбды с пустым списком захвата использует несмотря на использование окружающих переменных.
            Ответить
      • Лол. Напомнило беседу с начальником отдела по дружбе. Получил парень задачу добавить в редактор undo / redo возможности. Меня как старшего товарища позвлаи посмотреть, но уже когда все было решено.
        Я: Ну... а в какой структуре данных предполагается хранить историю изменений?
        НО: Я вот тут в каком-то блоге нашел <класс из огромного фреймворка, который уже несколько лет не поддерживается>, но в блоге было написано, что в нем есть проблемы, поэтому я решил использовать две копии этого класса: одну для undo, а другую - для redo.

        Как же оно все так сделано, что просто код нельзя писать, нужно обязательно там изолентой заклеить, тут напильником... Особенно порадовал самодельный gensym.
        Ответить
        • Если хочется настоящего говна и палок, советую полистать Modern C++ Design того же автора. Суть в том, что метапрограммирование на этом езыке родилось случайно, бьярне хотел просто std::vector сделать. Но пытливые умы времени даром не теряли.
          Ответить
          • Кстати, кто знает, при перемещении лямбды её объекты перемещаются?
            Ответить
            • > её объекты
              Да всяко должны. Это ж, по сути, обычная херь-с-оператором-скобки посыпанная сахарком. Но пруф/опровержение искать лень.
              Ответить
              • дык дефолтный оператор перемещения в крестах, если не перегружать специально - вызов оператора копирования делает вместо перемещения. такие дела. небось и блямбда такаяже
                Ответить
                • > вызов оператора копирования делает вместо перемещения
                  Схуяли? Это потому что ты написал свой конструктор копирования, а конструктор перемещения не написал. Если же оба конструктора по дефолту генерятся - то почленно перемещает то, что можно переместить.

                  Вот, мувает захваченную херню: http://ideone.com/7jFVrC
                  Ответить
                  • http://ideone.com/hwSPZj
                    да ты придумал. нихрена он не мувает. вообщем блямбда мувает, а класс нет
                    Ответить
                    • http://ideone.com/3tHMRl
                      ну а это прямо обратный эффект лол
                      Ответить
                      • Я просто оставлю это здесь: http://ideone.com/WqWFyY

                        Ну что там не мувается, няша :3 Дефолтовый конструктор правильно работает. Написал свой - отвечай за него сам.

                        Мы в ответе за тех, кого приручили.
                        Ответить
                        • http://ideone.com/RQjaJQ
                          Свои говноопределения конструктора копирования убрать и норм мувается
                          Ответить
                          • http://ideone.com/aw4gtZ
                            А вон в мув конструктора даже мувить члены не надо
                            Ответить
                            • > даже мувить члены не надо
                              Надо. Ты посмотри, где объект то остался...Оно же shared_ptr не мувнуло, а дефолтконструктнуло.

                              a.a is not null 0
                              a is not null 1
                              Ответить
                              • Получается если сделать структуру с дефолтными конструкторами с объектами, которые могут перемещаться, то поведение этой структуры будет меняться от стандарта к стандарту. В С++11 они начнут неожиданно перемещаться, хотя раньше всегда копировались, в том числе в сишке. В общем не годно. Ну и второе нарекание: нужно было добавить какой-нибудь дефолтный перемещающий op= и mtor, если класс пометить "крестиком", типа mtor() = default; Ну чтобы компиль сам сгенерировал перемещающий мтор, который бы перемещал объекты. Что позволило бы в мтор вручную не перечислять перемещаемые объекты. В старой студии последнего точно не было. Помоему или не компилировалось или копировало. Не знаю как по стандарту.
                                Ответить
                                • > начнут неожиданно перемещаться...
                                  ... в тех контекстах, в которых на это всем похуй. В остальных же без std::move перемещение не активируется.

                                  > дефолтный перемещающий op= и mtor,
                                  Вот этого не хватает, да. Не получается убить конструктор копий, оставив дефолтный перемещатор.
                                  Ответить
                                  • P.S. А если у класса описан деструктор, то автосгенерённый movector тоже отваливается. Поэтому никакого вреда для старого кода не будет... Ну, по крайней мере, я не могу придумать такого случая.
                                    Ответить
                                • Новый завет, глава 12.8, стих 10. Copying and moving class objects

                                  If the definition of a class X does not explicitly declare a move constructor, one will be implicitly declared as defaulted if and only if:
                                  — X does not have a user-declared copy constructor,
                                  — X does not have a user-declared copy assignment operator,
                                  — X does not have a user-declared move assignment operator,
                                  — X does not have a user-declared destructor, and
                                  — the move constructor would not be implicitly defined as deleted.
                                  Ответить
                    • > а класс нет
                      Всё там мувается, если руки не из ануса: http://ideone.com/TAOUDB
                      Ответить
                      • Не понял, почему второе не муванулось?
                        Ответить
                        • Потому что конструктор копий есть, а конструктор перемещений не пильнули.
                          Ответить
                          • И он по умолчанию не генерируется? А как его записать, но чтобы не перечислять все поля самому?
                            Ответить
                            • > чтобы не перечислять все поля
                              А выбора особо нету. Либо ты пишешь оба сам и полностью отвечаешь за их работу, либо пишешь один, а второй отваливается, либо ты ничего не пишешь, и получаешь почленное копирование/перемещение.
                              Ответить
                            • P.S. Причина, скорее всего, банальна. Раз у тебя есть нетривиальная логика в конструкторе копирования (ну ты же его не просто так писал?), то почленное перемещение будет бессмысленно, и лучше его не генерить, ибо полезут непредсказуемые баги.
                              Ответить
                              • Не согласен. Нетривиальное перемещение случается намного реже, чем нетривиальное копирование. Вообще для 99% классов даже memcpy сгодится (старый объект правда следует забыть, а не уничтожать, чего кресты не умеют).
                                Ответить
                                • > чем нетривиальное копирование
                                  Если правильно следовать RAII - то нетривиальное копирование встречается очень редко и только в низкоуровневых классах (реализации смартпоинтеров и т.п.). Я когда игровой сервачок писал just for fun, у меня там в сотне классов был один деструктор, и тот от лени. А нетривиальных копирований/перемещений вообще не было.
                                  Ответить
                                  • Согласен, ресурсы тоже должны быть каждый в своей обёртке.
                                    Ответить
                    • Ответить
                      • > Не ну блин, а какой должен быть эффект от мува инта? Он старое значение и оставляет валяться. Пирфоманса ради. Всё равно всем пофиг. Лишь бы какое-то согласованное состояние было.

                        Вообщет там указатель на инт и он замувился или скопировался и это разные вещи
                        Ответить
                        • Да я уже стёр то сообщение.
                          Ответить
                          • Иногда мне хочется изучить кресты только ради того, что бы понимать, о чем вы говорите
                            Ответить
                            • я только ради этого их и изучал
                              Ответить
                              • Посоветуйте какой книге отдаться, товарищ.
                                Ответить
                                • Когда приспичило, я смело начинал с Modern C++ Design александреску (правда, в универе пару раз пытался читать страуструпа). Потом Мейерс - тоже крайне полезное и интересное чтиво.

                                  Страуструп полезен и довольно полон, но невозможно скучен. Издание по C++03 я ещё осилил, а вот до свежего по C++11 я ещё не добрался.
                                  Ответить
                                  • А все это можно в VS проделать, или c++ от MS не кошерен и нужно ставить какой нибудь цивинг?
                                    Ответить
                                    • > c++ от MS не кошерен
                                      Ну хер знает, я давно уже вижуалку не видел. Самые-самые последние вроде кошерны. Ниже 2013 точно не стоит юзать.
                                      Ответить
                                    • Свежие VS вполне соответствуют стандарту, если не юзать всякие T_Tmain, и прочие виндострадания.

                                      Только ворнинги компиляции на максимум не забывай выкручивать.
                                      Ответить
                                      • > ворнинги компиляции на максимум
                                        А вижуалка уже перестала ругаться на свои же либы на максимальных уровнях?
                                        Ответить
                                        • Не знаю, я её только издалека видел.
                                          Ответить
                                        • Так гцц также на свои ругается. Впрочем там их принудительно давят по дефолту
                                          Ответить
                                    • >>и нужно ставить какой нибудь цивинг?
                                      >>>какой нибудь цивинг?
                                      >>>>>цивинг?
                                      Запомни, ассемблер - это компилятор.
                                      Ответить
    • - Ну ты чего заплакал, дурачок, я же с тобой, - Пашка гладил и лохматил мою голову, пытаясь успокоить, - ну что ты...
      Ответить

    Добавить комментарий