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

    +1

    1. 1
    2. 2
    3. 3
    // Всем привет. Я тоже принёс говнокода, но в необычном формате.
    // А именно, я написал мини-книгу "60 антипаттернов для С++ программиста".
    // https://pvs-studio.ru/ru/blog/posts/cpp/1053/

    Там вы найдёте и реальный C++ говнокод и просто вредные советы в духе "Пишите код так, как будто его будет читать председатель жюри IOCCC и он знает, где вы живёте (чтоб приехать и вручить вам приз)".

    Если сразу не понятно почему "совет" вреден, то там есть соответствующий разбор.

    Готов подискутировать про написанное. Ну и приглашаю накидывать в комментариях аналогичные советы.

    P.S. Предупреждаю: там много букв. Сразу запасайтесь кофе/энергетиком. Или попкорном :)

    Запостил: Andrey_Karpov, 15 Июня 2023

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

    • >Вредный совет N6. Невидимые символы
      >
      >Используйте при написании кода невидимые символы. Пусть ваш код работает магическим образом. Это прикольно.

      Я б этот вредный совет расширил до "Используйте побольше символов за пределами ASCII"
      Ответить
      • Смайлик говна какое-то время (а может и сейчас) был легальным символом в идентификаторах
        Ответить
    • >Вредный совет N31. Всё в h-файлах
      >
      >Побольше кода в заголовочных файлах, ведь так гораздо удобнее, а время компиляции возрастает очень незначительно.
      >
      >В эпоху моды на header-only библиотеки этот совет не кажется таким уж и вредным. В конце концов, существует даже "A curated list of awesome header-only C++ libraries".
      >
      >Но одно дело – маленькие библиотеки. А другое – большой проект, в который вовлечены десятки людей и который развивается многие годы. В какой-то момент время компиляции вырастет с минут до часов, а сделать что-то с этим уже будет сложно. Не рефакторить же сотни и тысячи файлов, перенося реализацию функций из *.h в cpp-файлы? А если рефакторить, то не проще ли сразу было делать нормально? :)

      А это уже проблема скорее компилятора, который не может быстро это делать. Допустим, есть некий .h файл где реализована некая шаблонная хренотень, есть куча .cpp файлов которые этот .h файл инклудят и каким-то образом используют, компилятор каждый раз с нуля все парсит в хедерах и специализирует, как это можно было бы исправить чтоб был быстро? Например, скомпилировать сам .h файл в некий промежуточный байткод, чтобы каждый раз не тратить время на его парсинг. Если во множестве файлов некий шаблон из хедера специализируется одним и тем же, это тоже можно как-нибудь закешировать и значительно ускорить компиляцию. Под что-то такое даже пилился специальный кеширующий компилятор zapcc https://github.com/yrnkrn/zapcc (основан на clang), но что-то не взлетело.
      Ответить
      • У многих компиляторов есть PCH — precompiled C headers, но реализован он страшно неудобно: хоть один из хедеров поменятся, и PCH собирается заново с нуля. И исправить это невозможно из-за самой природы макросов, потому что один хедер может портить своими макросами другой.
        Ответить
        • Но эти PCH никак не ускоряют инстанцирование какого-то шаблоноговна одинаковым образом в куче единиц трансляции.
          Ответить
          • Да, шаблоноговно — отдельная тема. Производители компиляторов не могут договориться, как их инстанцировать:

            https://gcc.gnu.org/onlinedocs/gcc/Template-Instantiation.html
            Ответить
    • Ура, Andrey_Karpov вернулся!
      Ответить
    • Про «UB» я бы вторым советом вынес. Абсолютно невыносимы питухи, которые пытаются оправдывать свои UB, а уж питухи, которые при этом с умным видом рассуждают, какой -O не «ломает их программу» — это вообще пиздец.
      Ответить
      • Но ведь -O действительно может сломать программу...
        Ответить
        • У Царя некоторые программы работали исключительно с -O2, а с -O0, -O1, -O3 и с прочими параметрами оптимизации падали, потому что с его точки зрения -O2 — единственно правильный ключ.
          Ответить
      • Не знаю, у меня на компьютере все работает
        Ответить
    • > Табуляция [в строковых литералах] в процессе рефакторинга или использования утилит автоформатирования кода может превратиться в пробелы, что повлияет на результат работы программы.

      Утилиты автоформатирования, которы трогают строковые литералы — то ещё говно.
      Ответить
      • Это уровень пиздец-оффтопа уже, они вообще не должны туда лазить, литерал — одна неделимая нода в parsing tree.
        Ответить
      • > Табуляция [в строковых литералах] в процессе рефакторинга или использования утилит автоформатирования кода может превратиться в пробелы, что повлияет на результат работы программы.

        Кривая утилита автоформатирования может и несколько пробелов скукожить в один(или заменить на таб), так что теперь, пробелы в строковых литералах не использовать?
        Ответить
        • > несколько пробелов скукожить в один
          Приоткрывается завеса на чём написана эта утялита.
          Ответить
      • >> Утилиты автоформатирования, которы трогают строковые литералы — то ещё говно.


        Это еще ничего. Некоторые утилиты автоформатирования и бизнес-логику править могут
        Ответить
        • Как вы такое юзаете? Если всё через жопу, то какой шанс на то, что сделает красиво?

          Единственный вариант вижу: немного кривой выхлоп утялиты случайно совпадает с немного кривым видением смузихлёба, а потом немного кривой стартап и целая стая приматов с этим все живет от получки до получки
          Ответить
    • Уважаемый Вячеслав Владимирович! Убедительно просим Вас обратить внимание на нашу проблему: с. Новая, Таволжанка, ул. Волчанская. Во многие дома проникают военнослужащие РФ(хотя режима ЧС не введено и они не имеют права заходить в частные домовладения). Они живут в наших домах, ведут безобразный образ жизни, алкоголь и прочее остаётся в виде мусора и грязи, загажены туалеты и дома,воруются личные вещи и имущество. Из нашего гаража был украден квадроцикл, который теперь часто видят в округах Новой Таволжанки. Кроме этого люди жаловались на украденный прицеп. Теперь он катается вместе с нашим квадроциклом. Мы очень просим помочь в нашем вопросе. Мы не хотим, чтобы наши дома, которые итак пострадали от действий ВСУ, теперь были ещё пристанищем для безобразий наших защитников!

      https://vk.com/wall639631882_932848?reply=932944

      Унитаз воровать невыгодно через 3... 2...
      Ответить
      • а тем у кого нагадили в доме? Куда смотрит власть???? Куда стучать???? Шойгу твои военные у нас воруют! Российские военные у российских гражданских людей воруют и там же срут!!! Позор власти, Позор Шойгу, Позор русскому солдату!!!

        п-р сркн
        Ответить
      • Наталья, квадроцикл с прицепом даже в Ютуб попал. Там и правда, военные на нем. https://youtu.be/830rPQvFyIc на 3 мин.13 сек. можно увидеть.
        Ответить
    • Хорошие советы, но некоторые очень уж юниорски (типа глобальных переменных)
      Буду писать по комментарию про совет раз в час
      Ответить
    • Совет 1:

      >>
      Плохо, когда начинают использовать этот язык только потому, что это "круто" или это единственный язык, с которым хорошо знакома команда.
      >>

      Я бы разделил эти два понятия. "Круто" -- это для школьников, а вот выбирать язык потому, что с ним хорошо знакома ваша команда -- вполне логично.

      Я чаще вижу обратную проблему: люди берут какой-нить Python "потому что нужно быстро", а потом у них все тормозит.
      Ответить
    • Совет 2:

      >>случается, что программист вместо того, чтобы использовать '\t', не задумываясь, просто нажимает кнопку TAB.

      Это странный аргумент. Случается так, что программист вместо "gcc" случайно нажимет "rm / -rf", но это не повод не пользоваться gcc.

      >>На самом деле в литерале могут оказаться не табы, а пробелы. Это зависит от настроек редактора.

      Пожалуйста всегда имейте одинаковые настройки у всех программистов проекта, и храние их в VCS, иначе у вас отбивка в каждой функции будет зависеть от предпочтений программиста

      >>Явные символы табуляции использовались в перемешку с пробелами.
      кошмар))) но я на лабах такое видел
      Ответить
      • Есть текстовые редакторы, которые заменяют табы на пробелы или пробелы на табы. Например, IDE на Turbo Vision так делали (там в настройках была галочка, причём вариант «ничего не заменять» отсутствовал).
        Ответить
    • https://pbs.twimg.com/media/FxDmHNRXsAEG7Dw?format=jpg&name=large
      Ответить
    • Совет 3.

      >>Вложенные макросы

      Мне кажется, что макросы нужны только для совместимости с си. В плюсах макросы не нужны почти никогда.
      Ответить
      • Действительно, если в сишке ещё использовали #define для эмуляции именованных констант, то в крестах есть const.

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

        Что остаётся? #ifdef да #include. Остальные возможности макросов разве что для отладки.

        Чуть не забыл про constexpr и consteval, которые могут в компилтайме выполнить то, что раньше делали макросами.
        Ответить
        • В макросах ещё остаётся ещё стрингификация идентификаторов.

          Чтобы делать что-то типа:

          LOG(huita)

          >> Value of "huita" is: 42
          Ответить
          • А, вот что, оказывается, означает «для кривой мумуляции компайлтайм-рефлексии».
            Ответить
      • К слову, какой ещё ЯП, кроме сишки, придумали Керниган и Ритчи? Они ещё предлагали на нём писать макросы.
        Ответить
        • B:)

          А еще awk: папу перла, дедушку руби
          Ответить
          • Ещё m4, которым можно детей пугать.
            Ответить
          • Глянул статейки про CPL и BCPL, которые почему-то считаются предшественниками Би и Си. Ничего общего. В CPL и BCPL был паттерн-матчинг и другие интересные штуки, которые сишкой были похоронены на долгие годы, потому что K&R не смогли сделать эффективную реализацию и урезали всё, что могли.
            Ответить
      • Пока ещё нужны для кривой мумуляции компайлтайм-рефлексии. Когда её завезут по-настоящему — тогда можно будет хоронить, да.
        Ответить
        • Макросы позволяют делать хуйню, которую принципиально без макросов пока никак не сделать, и которая к компилтайм-рефлексии прямого отношения не имеет.
          Вот взять пример из https://gcc.gnu.org/onlinedocs/cpp/Stringizing.html :
          #define WARN_IF(EXP) \
          do { if (EXP) \
                  fprintf (stderr, "Warning: " #EXP "\n"); } \
          while (0)

          Как это переписать без макроса, и при чем тут компилтайм-рефлексия?
          Ответить
          • >> и причем тут компилтайм-рефлексия?
            >>#EXP
            Ответить
            • И как стрингификация относится к компилтайм-рефлексии?
              Ответить
              • Потому что стрингификация это частный случай рефлексии.
                Ответить
                • Почему это стрингификация является частным случаем рефлексии?
                  Ответить
                  • По определению, рефлексия – это:

                    Отражение (рефлексия; холоним интроспекции, англ. reflection) — процесс, во время которого программа может отслеживать и модифицировать собственную структуру и поведение во время выполнения (мы говорим про рефлексию времени компиляции, к слову). Парадигма программирования, положенная в основу отражения, является одной из форм метапрограммирования[1] и называется рефлексивным программированием.

                    Таким образом, раз программа во время компиляции отслеживает собственную структуру (имена переменных), то это – частный случай рефлексии.
                    Ответить
                    • Макроговно никакие "имена переменных" не отслеживает, ни про какие имена переменных оно не знает, оно делает тупую подстановку текста по шаблону, т.е. рефлексией это не является.
                      Ответить
                      • Макроговно поддерживает операцию: "получить имя переменной", это – частный случай рефлексии, т.к. отслеживаются метаинформация программы.
                        Ответить
                        • никакое "имя переменной" оно не получает, оно тупо стрингифицирует некую хуету
                          Ответить
                          • То, что ты описал – это детали реализации. И это не меняет того факта, что в C есть интерфейс для получения имени переменной из исходного кода, что и является частным случаем метапрограммирования.
                            Ответить
                            • Нет, никакого получения имени переменной там нет. Там есть стрингификация.
                              Ответить
                              • Я и не говорил, что оно есть. Я сказал, что существует интерфейс для получения имени переменной во время сборки. То, что он реализован с помощью подстановок и макросов – это деталь реализации, и вовсе не главное.

                                Ты не прав, а я – прав. Потому что я выучил сишку.

                                Ты сейчас похож на человека, который не верит, что на C можно писать в ООП парадигме, т.к. в C отсутствуют т.н. "классы".
                                Ответить
                              • Он, как попка, – «Си» да «Си»,
                                Ну а сам все налегает
                                На селедку иваси!
                                Ответить
                                • Помолюсь, как говорится, Аллаху
                                  И рубаю в маринаде салаку.

                                  А на утро я от жажды мычу,
                                  И хоть воду мне давай, хоть мочу!
                                  Ответить
    • * Вредный совет N4. Выключить предупреждения

      ну тут без комментариев. За заметание мусора под ковёр нужно гнать из профессии, да

      >>Старайтесь, чтобы при компиляции проекта у вас не выдавалось ни одного предупреждения.
      охох, может быть вам еще и 40 мигающих тестов не нравятся?:)

      >>Вредный совет N5. Чем короче имя переменной, тем лучше
      А вот в языке Го принято ИНОГДА давать корткие имена переменным (заместо this)
      https://github.com/golang/go/wiki/CodeReviewComments#variable-names

      Кроме того, есть всякие for(i и пр

      Сокращать имена можно (arr и vec вместо array и vector, например)

      >>Вредный совет N6. Невидимые символы
      ну тут я могу только троллфейс нарисовать
      Ответить
    • . 
       * p v s * p v s * p v s * p v s * p v s * p v s * 
       p                                               p  
       v /     \             \            /    \       v  
       s|       |             \          |      |      s  
       *|       `.             |         |       :     *  
       p`        |             |        \|       |     p  
       v \       | /       /  \\\   --__ \\       :    v  
       s  \      \/   _--~~          ~--__| \     |    s  
       *   \      \_-~                    ~-_\    |    *  
       p    \_     \        _.--------.______\|   |    p  
       v      \     \______// _ ___ _ (_(__P  \   |    v  
       s       \   .  C ___)  ______ (_(____V  |  /    s  
       *       /\ |   + ____)/ viva \ (_____S  |_/     *  
       p      / /\|   +_____)   64  |  (___>   /  \    p  
       v     |   (   23_____)\______/  // _/ /     \   v  
       s     |    \  |__   \\_________// (__/       |  s  
       *    | \    \____)   `----   --'             |  *  
       p    |  \_          ___\       /_          _/ | p  
       v   |              /    |     |  \            | v  
       s   |             |    /       \  \           | s  
       *   |          / /    |  U   B  |  \           |*  
       p   |         / /      \__/\___/    |          |p  
       v  |         / /        |    |       |         |v  
       s  |          |         |    |       |         |s  
       * p v s * p v s * p v s * p v s * p v s * p v s *
      Ответить
    • > Вредный совет N48. У каждого свой стиль

      Мне искренне жаль автора, если он даже про утилиту "Indent" не слышал.
      Ответить

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