Кресты / Говнокод #17731 Ссылка на оригинал

0

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
void f(bool *ok = 0)
{
    //тут возникла ошибка
    if (ok)
        *ok = false;
    return;
}

//далее в коде
bool ok = false;
f(&ok);

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

Запостил: blackhearted blackhearted, (Updated )

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

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

    void f(bool *ok = 0, bool *ok_2 = 0, bool *ok_c = 0, bool *okok = 0, bool *ohreally = 0)
    Ответить
  • Долой исключения! Даешь хардкорные указатели!!!
    Ответить
  • Мне для обработки ошибок нравится православный Either, для крестов Александреску переизобрёл вот такое его воплощение
    http://channel9.msdn.com/Shows/Going+Deep/C-and-Beyond-2012-Andrei-Alexandrescu-Systematic-Error-Handling-in-C
    Код у александрески слегка косячный (да, даже александреску косячит, когда пишет на крестах), но идея весьма неплохая.
    Ответить
    • Блин, 1.5 часа видео. А нету текстового описания идеи?
      Ответить
        • Забавно - Александреску привёл в пример Maybe из хаскеля и само-собой обосрал его за то, что исключение в него не положить. А про Either скромно умолчал 🙂
          Ответить
            • Да ещё и читерская реализация через union. Хотя, согласен, реальную реализацию optional'а на коленке не накидать и на одном слайде не показать.
              Ответить
                • Ой. А я и не думал, что в c++11 можно и нетривиальную фигню в юнион засунуть. Годная фича. Можно подразнить Тараса.
                  Ответить
          • Расскажите что там, вкратце суть идеи, а то MS Word даже в онлайне говно - у меня ничё не показует.
            Ответить
              • Бля, ну вот я много понял, да. Тем более что борманд выше его уже упоминал.
                Я-то домыслил что метаданные разных типов заворачиваются, при успехе/ошибке, и какой профит с этого?
                Ответить
                • В переводе на жабу что-то вроде этого:
                  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(); без всяких юзингов и тайпдефов.
                            Ответить
                            • Я смотрю он свой скоп_гуард доработал до поддержки комита транзакции.

                              А не знать о Эйзе из хаскеля - это глупо с его стороны
                              Ответить
            • Ну а кто ещё редистрибьютит, когда написано:
              > 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/WqWFyY

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

                      Мы в ответе за тех, кого приручили.
                      Ответить
                          • > даже мувить члены не надо
                            Надо. Ты посмотри, где объект то остался...Оно же 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.
                                Ответить
                      • Потому что конструктор копий есть, а конструктор перемещений не пильнули.
                        Ответить
                        • И он по умолчанию не генерируется? А как его записать, но чтобы не перечислять все поля самому?
                          Ответить
                          • > чтобы не перечислять все поля
                            А выбора особо нету. Либо ты пишешь оба сам и полностью отвечаешь за их работу, либо пишешь один, а второй отваливается, либо ты ничего не пишешь, и получаешь почленное копирование/перемещение.
                            Ответить
                          • P.S. Причина, скорее всего, банальна. Раз у тебя есть нетривиальная логика в конструкторе копирования (ну ты же его не просто так писал?), то почленное перемещение будет бессмысленно, и лучше его не генерить, ибо полезут непредсказуемые баги.
                            Ответить
                            • Не согласен. Нетривиальное перемещение случается намного реже, чем нетривиальное копирование. Вообще для 99% классов даже memcpy сгодится (старый объект правда следует забыть, а не уничтожать, чего кресты не умеют).
                              Ответить
                              • > чем нетривиальное копирование
                                Если правильно следовать RAII - то нетривиальное копирование встречается очень редко и только в низкоуровневых классах (реализации смартпоинтеров и т.п.). Я когда игровой сервачок писал just for fun, у меня там в сотне классов был один деструктор, и тот от лени. А нетривиальных копирований/перемещений вообще не было.
                                Ответить
                                • Согласен, ресурсы тоже должны быть каждый в своей обёртке.
                                  Ответить
                    • > Не ну блин, а какой должен быть эффект от мува инта? Он старое значение и оставляет валяться. Пирфоманса ради. Всё равно всем пофиг. Лишь бы какое-то согласованное состояние было.

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

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

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

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

Семь раз отмерь — один отрежь, guest!

    А не использовать ли нам bbcode?


    8