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

    +4

    1. 1
    2. 2
    3. 3
    4. 4
    5. 5
    6. 6
    7. 7
    8. 8
    #include <chrono>
    #include "SomeShittyLib.h"
    
    // ...
    
    //Fuck you.
    #undef min
    auto min_seconds = std::chrono::seconds::min();

    Конечно, каждому либописателю надо объявить макрос min "(((a) < (b)) ? (a) : (b))", ведь вызов функции - это пиздец какие накладные расходы!

    Запостил: gost, 14 Октября 2017

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

    • std::min/max это пздц, если честно. Возвращает ссылку, принимает lvalue-ссылки, не принимает переменные разного типа. В половине случаев непригоден ;(
      Ответить
    • Надо каждой функции иметь по две: в виде макроса и в виде собссно функции

      Первый вариант оптимизирован по размеру
      Второй -- по скорости
      Ответить
      • Макросы ради скорости/размера юзали от безысходности, когда конпеляторы ещё не умели инлайнить.

        В общем, нахуй и в пизду такие предложения. Особенно для крестов, где потребность в макросах намного ниже, чем в няшной.
        Ответить
        • а какой смысл в мокросе для max? чем он лучше функции?
          тем что полиморфен?
          Ответить
          • Макросы для max() лезут из сишных либ, где другого способа попросту нет.

            З.Ы. А за именование макроса не капсом надо вешать, потрошить и четвертовать. Привет чувакам из майкрософт, которые понадефайнили всякой хуйни в духе min, max и interface.
            Ответить
            • > понадефайнили всякой хуйни в духе <...> interface
              С недавнего Qt World Summit 2017:
              https://twitter.com/qtproject/status/918389537843417093
              https://pbs.twimg.com/media/DL7GaqrX4AARW79.jpg:large
              Текстовое представление: Герб Саттер предложил
              // C++17
              class Shape {
              public:
                  virtual int area() const =0;
                  virtual void scale_by(double factor) =0;
                  virtual ~Shape() noexcept { };
              
                  // careful not to write a nonpublic or
                  // nonvirtual function, or a copy/move
                  // operation, or a data member; no
                  // enforcement under maintenance
              };
              заменить на
              // Proposed
              interface Shape {
                  int area() const;
                  void scale_by(double factor);
              
                  // default + enforce: all public pure virtual functions
                  // enforce: no data members, no copy/move
              };
              Любопытно будет почитать твиттерное нытьё разрабов вижуальника, если это примут.
              Ответить
              • Можно было просто добавить в язык интерфейсы, но крестоблядь саттер придумал замороченную метушню, с помощью которой интерфейсы можно будет сделоть (но естественно никто не будет этим пользоваться кроме отмороженных метухов, так же как сейчас никто не проверяет методы на этапе конпиляции). Так по-крестоблядски.
                Ответить
                • > просто добавить в язык интерфейсы
                  Да заебали уже просто добавлять в язык очередной частный случай, честное слово...

                  > замороченную метушню
                  В кои-то веки придумали единственную годную фичу за все последние годы - компайл-тайм рефлексию и генерецию кода. Но эту фичу не примут, не по крестоблядски это - крестухам будет обидно, что половина их метушения с шаблонами, макросами и внешними генераторами станет нинужной, да и новые фичи в язык каждый год добавлять уже не получится.
                  Ответить
                  • > Да заебали уже просто добавлять в язык очередной частный случай
                    Что плохого? От того что в язык добавят обобщенную метамокропиську, интерфейсы сами не появятся - все равно их нужно будет добавлять в язык. Свои интерфейсы в каждом проекте - это плохо. Как бы не был плох го, но то что там у всех все одинаково и все гоферы понимают код друг друга - это сильная сторона языка.
                    Я тут где-то уже говорил, что язык для создания диалектов != язык программирования. Программисту нужен ЯП, а не конструктор сделай сам.
                    Ответить
                    • Мне кажется что кроме крестов и перла вообще программисты обычно понимают друг друга)

                      не нужен конструктор? а как же DSL?
                      Некоторые япы (груви, например) прямо таки позиционирует себя как ЯП для DSL
                      Ответить
                      • > DSL
                        Ненужно. Делать мне нечего, как в каждом хеловорлде с новым дслем разбираться.
                        Ответить
                        • Ты против DSLей впринципе?
                          Graddle, puppet, Vagrant итд же
                          много их
                          Ответить
                          • Нет, я не хочу, чтобы программисты городили свой принципиально новый дсл для каждой программы. А если кресты предоставляют только средства для создания дслей вместо средств для написания программ, то у крестушков не останется выбора.
                            Ответить
                    • > Программисту нужен ЯП, а не конструктор сделай сам.

                      Блин, одному программисту нужны инструменты/библиотеки, чтобы писать утилиты, второму нужны выразительные средства языка, чтобы писать те самые инструменты и библиотеки. По факту метаклассы нужны чтобы многие фичи реализовывать и протаскивать в стандарт за пару месяцев в виде библиотек, а не 5 лет в виде language core feature. А первой категории кодеров будет глубоко похуй, interface это метакласс, расширение компилятора, макрос ебанософта или ключевое слово языка; лишь бы работало
                      Ответить
                      • Инструменты и библиотеки пишут программмсты на языках программирования, а на метамокрописьках крестобляди пишут метушню. Прошу не путать.
                        Ответить
                        • прошу не путать быдлокодеров, способных только на фреймворке реализовывать отдельные фичи приложения; и программистов, которые пишут эти фреймворки и каркассы тех самых приложений. Второе требует куда большей квалификации.
                          Ответить
                          • Не представляю, что происходит в твоей голове. Как можно на полном серьезе утверждать, что индустрия держится на метухах, что именно метухи делают некие божественные фреймворки, без которых программисты и хеловорлд не напишут? Охуеть.
                            Ответить
                            • утверждаю я лишь что метапрограммирование сложнее и требует более высокой квалификации; позволяя, взамен, писать более корректный/быстрый/лаконичный код.

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

                                  Для хорошего метушения надо быть метаметапрограммистом. А у нас больше воюют с реализацией. Не поняли, наследовать int от real, или наоборот - создали общего предка "Number"; не смогли реализовать оптимально математическую запись - ввели указатели и возню с памятью; не смогли в неявную асинхронность - ввели коллбеки, async/await. И получается, что код, решающий вопросы доставки угля, не про поезда и грузовики, а про абстрактные фабрики фабрик, генераторы итераторов и темплейт визиторы.

                                  Потому-то метушня с абстракциями частенько вредят, выделяя шизофренически точно какие-то побочные общие признаки кода.

                                  Но без этого приходится как кэп писать циклы с i от 0 до 10 и дублировать код.
                                  Ответить
                                  • > Если не пытаться натягивать реальный мир на манямирок
                                    ... то не будет ни mpl, ни констекспров, ни статик ифов, ни метакласов, ни даже кривого std::variant (вместо него нормальный синтаксис, встроенный в язык), а крестобляди будут уныло писать классы и функции, и дергать письку на свою илитность уже не получится...
                                    Ответить
                                    • > уныло писать классы и функции
                                      Ну уныло же. Натягивать реальный мир на манямирок классов и функций - тоже не дело. Они не везде удачно описывают суть.
                                      Ответить
                                    • и какой же variant в твоем понимании будет нормальным?
                                      Ответить
                                      • Как в расте: тайпсейфный, с удобным патернматчингом, и красивым синтаксисом.
                                        Ответить
                                • ну тут уже я чисто из опыта говорю: корректное использование stl уменьшает объем си-подобного кода в ~2-3 раза при том, что код обычно становится более простым. Например, очевидно, что делают std::rotate/reverse. В виде цикла на чистом си это несколько строк, назначение можно понять только вчитываясь. std::unique_ptr с кастомным deleter'ом не единожны упрощал мне жизнь, когда доводилось работать с winapi, например, когда приходилось делать что-то подобное:
                                  https://msdn.microsoft.com/en-us/library/ms676882(v=vs.85).aspx
                                  7 уровней вложенности складывались в два. Или, из недавнего: в одном проекте простой шаблон:
                                  template <typename T>
                                  using aligned_vector = std::vector<T, aligned_allocator<T,16>>;

                                  избавил меня от кучи жонглирования с _mm_alloc/_mm_free/unsafe cast. std::complex<float32x4> и вся комплексная арифметика определена для sse3.

                                  Ко всему надо подходить с умом. В противном случае так и будешь кукарекать о том, что вокруг одни метухи
                                  Ответить
                                  • Вроде ты никакой особой метушни не назвал. Я не считаю, что дженерик контейнеры или смартпойнтеры не нужны.
                                    Ответить
                                    • > смартпойнтеры
                                      Костылики. Пример полезной удобной абстракции, сильно облегчающей жизнь, реализованной метушками, но появившейся из-за того, что жизнь когда-то была начата неверно.

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

                                        И что оказывается? Что же пошло не так? Всё пошло не так.

                                        Хотели выразительный язык, чтоб говорить с компьютером как можно более естественным образом, а получили феню и школоло-мемасики. Или какие-то абстрактные абстракции, или модные словечки и частные случаи навпихуивали. Чтоб не выстрелить себе в ногу, надо читать книги на 1200 страниц. Чтобы объяснить компьютеру программу, надо писать не на псевдоанглийском, а переписать её на английский язык курильщика канцелярита, пропустить понятия реальной жизни через призму парадигмы, несоответствия прикрыть фиговым листком.
                                        Ответить
                                        • Кажется, у тебя началась wvxvwянка. Срочно в карантин.
                                          Ответить
                                          • Он тоже зафакапил проект на плюсах и теперь перекатывается напитон?
                                            Ответить
                                            • У wvxvw все хуже гораздо было.

                                              В одной комнате сидели чуваки, и писали на go.
                                              В другой комнате сидели чуваки, и писали на питоне.

                                              Первые сорвали сроки, а вторые нет.

                                              Отсюда он делает логичный вывод что go -- говно, а питон нет.
                                              Ответить
                                              • Ну а как ещё эффективный менеджер может оптимизировать выполнение сроков?
                                                Ответить
                                        • Хуёвое дело -- программирование. Завязывать надо.
                                          Ответить
                                          • Для того, чтобы писа́ть простыни по программированию, вовсе не обязательно программировать.
                                            Ответить
                                            • Да, можно писать книги "C++ для професисоналов" для издательства BHV
                                              Ответить
                                    • ну так кто-то же их писал, эти контейнеры и смартпоинтеры. И писал на шаблонах
                                      Ответить
            • dxd@Paymon /home/dxd# grep -r '^#define\s\+[a-z_]\+\s' /usr/include|wc -l
              2881


              Как будто только мс грешен.
              Ответить
              • надо исключить из поиска макросы, начинающиеся на __. Стандарт резервирует эти имена для реализации фич компиляторов. Сейчас в gcc очень много таких макросов используются для gnu++1z расширения с концептами

                один фиг Гвидо в этом никто не переплюнет. #define hypot _hypot в python.h
                Ответить
                • еще, кстати, стандарт СИ требует чтоб некоторые функции были реализованы в виде макросов
                  Ответить
                  • У этого требования есть разумное обоснование?
                    Ответить
                    • Да скорее всего для компайл-тайм проверки их наличия.
                      Ответить
                    • да. В си нет перегрузок, поэтому вся математика реализована на type-generic макросах:
                      http://en.cppreference.com/w/c/numeric/tgmath

                      Еще есть всякие offsetof, которые все всю жизнь реализовывали через жмакрос с формальным UB
                      Ответить
                      • > type-generic
                        Блин, а как это вообще запиливали до С11?
                        Ответить
                        • __builtin_...
                          Ответить
                          • Оказывается, даже без builtin умудрялись запилить: https://web.archive.org/web/20131205042841/http://carolina.mff.cuni.cz/~trmac/blog/2005/the-ugliest-c-feature-tgmathh/

                            З.Ы. Кому вообще понадобилась вся эта type-generic математика в системном языке? Вендоры сишных конпеляторов хотели перетянуть себе часть юзеров с фортрана?
                            Ответить
                            • __typeof__ же нестандартное расширение
                              Ответить
                              • Как-будто statement expressions, которые они там ниже юзают, есть в стандарте :)
                                Ответить
                    • Я пока в стандарте только вот такое нашёл:
                      Any function declared in a header may be additionally implemented as a function-like macro defined in the header, so if a library function is declared explicitly when its header is included, one of the techniques shown below can be used to ensure the declaration is not affected by such a macro.

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

                      А требование нашлось пока только для ассёрта.
                      Ответить
                      • >>брать адрес
                        у макроса?
                        Ответить
                        • У функции. function-like макрос же раскрывается только если после его имени скобочки стоят.
                          #define getc(f) getc(f)
                          getc(f); // вот тут раскрылся макрос
                          &getc; // а тут мы взяли адрес функции
                          Ответить
                          • ключевое слово функшен-лайк видимо

                            потому что если у тебя макрос определен как обычное выражение то я не оч понимаю как у него взять адрес
                            Ответить
                          • В упомянутом бложике есть ещё пример:
                            return (cos) (x);

                            cos взяли в скобки, чтобы макрос не раскрылся.
                            Ответить
                            • > взяли в скобки, чтобы макрос не раскрылся.
                              Ну вот, а Борманд что-то разнервничался из-за макросов. Берём всё в скобки - и ничего не раскрывается.
                              Ответить
                              • Макрос с параметром не раскрывается, если его имя взять в скобки.

                                А что делать с макросами без параметров?
                                Ответить
                                • Это уже другая история. Можно для всех используемых идентификаторов создавать макросы без параметров, осуществляющие тождественные преобразования. Тогда код сразу не скомпилируется, если будет конфликт.
                                  Ответить
              • не сиди под рутом

                К сожалению в си нет уобщепринятого кодстайла (как в жабе или сисярп), так что Борманд не прав.

                Разные либы имеют разные подходы

                А у яблок и вовсе макросы косят под функции
                например XCTAssert это мокрос
                Ответить
                • > Разные либы имеют разные подходы
                  Да пошли они нахуй со своим макроговном, засирающим глобальный неймспейс!

                  У себя в реализации пусть хоть if'ы редефайнят, лишь бы из публичных хедеров не торчало.
                  Ответить
                  • Я говорил больше про няшечку и обжектив (раз речь про яблоки)
                    там нету неймспейса в крестовом понимании
                    Ответить
                    • > нету неймспейса
                      В формальном крестовом понимании, конечно, нету. А в более общем - есть и не один. В няшной же тайпдефы/переменные и структуры живут в разных "неймспейсах". Плюс более приоритетный "неймспейс" препроцессора.

                      И вот если имя моей функции или переменной, пересечётся с чем-то, что торчит из хедера какой-то другой либы, то я получу внятную ошибку. А если с макросом - то кровь-кишки, в худшем случае это даже скомпилится но будет делать что-то совершенно левое.
                      Ответить
                      • Для этого те же яблочники юзают префикс: NS, UI итд.

                        Двух букв хватит всем!!

                        А в няшной каждый дрочит, как он хочет

                        у кого pthread_, у кого Nt.

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

                            Про таргет -- ок
                            Согласен
                            Ответить
                            • > клаша твоей функции с макросом
                              Не увидит, да и не должна - они же в разных "неймспейсах" и всякие #define cos(x) cos(x) вполне допустимы.

                              Она, конечно, подсветит кейс когда макрос раскрывается в какую-то хуйню, которая не сможет скомпилится... Но мы же о случае, когда даже конпелятор не заметил подвоха.
                              Ответить
                              • они в разных немспейсах, но IDE на то и IDE чтобы понимать хотя бы простые случаи.

                                IDE в любом случае знает и твои макросы и твои функции (Если конечно ты не генеришь функции через макросы) потому что у IDE есть парсер и лексер, и комплишен же как-то раблтает
                                Ответить
                            • Пример:
                              #include <Windows.h>
                              
                              class Foo {
                                  void CreateFile() {
                                  }
                              };
                              Вот эта хуйня скомпилится в Foo::CreateFileW. Успешно скомпилится, и даже будет работать (разве что CreateFile будет подсвечен немного не тем цветом, как обычно). Но слинковаться с файлом, где windows.h не инклудили, увы, не удастся.
                              Ответить
            • > З.Ы. А за именование макроса не капсом надо вешать, потрошить и четвертовать.

              Помню как я когда-то через макрос перегружал функции malloc calloc и free, чтоб посчитать количество этих вызовов и убедиться что вся выделенная память всегда освободжается
              Ответить
    • Если запилят модули, то канпелять C++ можно будет вообще без cpp-говна.
      Ответить

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