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

    0

    1. 1
    2. 2
    3. 3
    4. 4
    5. 5
    6. 6
    7. 7
    8. 8
    // https://habr.com/company/JetBrains/blog/249479/
    
    Привет, Хабр!
    
    Некоторое время назад мы объявили конкурс — требовалось продолжить фразу:
    Бьёрн Страуструп создал С++ 36 лет назад, и он до сих пор востребован и пользуется популярностью у разработчиков, потому что...
    
    Спасибо всем участникам за массу положительных эмоций и разнообразные предположения о том, что же сделало C++ таким популярным.

    Посовещавшись, мы выбрали топ-6 ответов:

    Запостил: j123123, 16 Июля 2018

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

    • Бьёрн Страуструп создал С++ 36 лет назад, и он до сих пор востребован и пользуется популярностью у разработчиков, потому что помимо языка Бьёрн изобрел также капсулу времени и ионный бластер, с помощью которых он уничтожает все альтернативные реальности, в которых C++ непопулярен.

      НО в какой-то момент из-за buffer overflow заглючила прошивка в капсуле времени, и его отбросило в прошлое к динозаврам, которые разьебали его капсулу нахрен
      Ответить
    • Бьёрн Страуструп создал С++ 36 лет назад, и он до сих пор востребован и пользуется популярностью у разработчиков, потому что он лучше любого другого языка позволяет разрабатывать программное обеспечение, предназначенное для работы на платформах с произвольными ограничениями, будь то частота процессора, объём оперативной памяти или размер батарейки. А ещё, в отличии от plain C, в нём есть деструкторы!

      Произвольными ограничениями? Сделайте мне плюсы под Сетунь. Или например попробуйте плюсовую стдлибу (которая часть стандарта) и свои сраные деструкторы заюзать в 8-битных говноконтроллерах.
      Ответить
      • >Или например попробуйте плюсовую стдлибу (которая часть стандарта) и свои сраные деструкторы заюзать в 8-битных говноконтроллерах.

        Прикрутить кресты к контроллерам уже давно пытаются.
        https://habr.com/post/149683/
        У ардуинщиков вроде тоже какая-то кастрированная версия стдлибы есть.
        Ответить
        • > https://habr.com/post/149683/
          > STL
          > Я видел много сообщений, что STL на микроконтроллере — это плохо: она раздувает код и, делая сложные вещи простыми, подстрекает ими пользоваться. При этом умалчивается, что в STL есть и такие примитивы, как быстрая сортировка, которая значительно быстрее и компактнее qsort, или бинарный поиск, безопасные версии min и max. Вы правда знаете сакральный способ написать классические алгоритмы эффективнее других программистов?


          Да, если речь идет об AVR-GCC, я уверен что я на ассемблере могу написать qsort, быструю сортировку и бинарный поиск быстрее и компактнее, чем я получу от компилятора. У AVR-GCC очень плохо с оптимизацией
          Ответить
      • > 8-битных говноконтроллерах
        Кстати, а для чего 8-битные AVR сейчас юзают в продакшене? Я ещё понимаю для DIY-говна всякого -- маленький порог вхождения, пятивольтовый интерфейс и корпус который легко запаять неопытными лапками. Но ведь 32-битные cortex'ы выходят и мощнее и дешевле (и жрут меньше, да)...
        Ответить
        • В продакшене и 8051 юзают, и как бы не чаще чем АВР. "Надо переходить на 32 бита" - пишут ещё с 2009 года, или когда там дешёвые кортексы выкатили.

          >и жрут меньше, да
          Последние ревизии AVR жрут как стандартные stm32(по поводу low power чипов х.з.).
          Ответить
        • > Но ведь 32-битные cortex'ы выходят и мощнее и дешевле (и жрут меньше, да)...
          Лучше дождаться швабодных непатентованных контроллеров на RISC-V, вон Arm Holdings уже на них пробует бочку катить https://archive.fo/SkiH0 - довольно оперативно потерли свой GetTheFuckts
          Ответить
    • мир захватывают самые практичные, а не самые красивые.

      Практичность это не тогда, когда надо лепить ебучую лапшу из шаблонов, как это сделано например в бусте
      Ответить
      • Глядя на последние 15 лет "прогресса" особенно в области "веба" я бы сказал что мир захватывают самые посредственные
        Ответить
    • Бьёрн Страуструп создал С++ 36 лет назад, и он до сих пор востребован и пользуется популярностью у разработчиков, потому что «C++» у вас написан кириллицей, а он таких ошибок не прощает.

      Интересно, а в "1C" буква C правильно пишется кириллицей или латинницей?
      Ответить
    • Бьёрн Страуструп создал С++ 36 лет назад, и он до сих пор востребован и пользуется популярностью у разработчиков, потому что позволяет придерживаться золотой середины между сложностью и производительностью.

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

      Че, серьезно? Т.е. разработчиков под obj-c найти нынче нереально? Знание плюсов разве не подразумевает автоматически знание Си (учитывая что Си это почти подмножество плюсов)?
      Ответить
      • obj-c не имеет станданртной кросс-платформенной либы, сишечка прекрасна то видимо иногда люди не хотят вручную склеивать строки
        Ответить
        • Фундейшен есть в опен-степе, но кому он нужен этот опен-степ?
          Ответить
          • и насколько он совместим с яблочным?
            Ответить
            • Совместим ограничено, хотя обратной нету точно, яблочники давно внедрили в фундейшен своих шлюх и блэкджек, которые опен-степ не поддержит и если открыть стандарт на объектный си (если он есть) то там яблочного ноу-хау тоже может не быть.
              Ответить
              • >>стандарт на объектный си (если он есть)
                а он есть?
                Ответить
                • А вот ХЗ
                  Ответить
                • Вроде бы нет, хотя встречал людей, утверждавших, что он существует (вероятно, или в их голове, или где-то в сейфе в Купертино). Нет особого смысла в языке, который существует ровно на одной платформе.
                  Ответить
                  • Ну вот в том-то и дело что его нет.
                    А когда у тебя все нчиная с NSObject не стандартизированно и имееца только в виде реализации под одну ОС и документировано там же на сайте apple, то как-то смешно говорить про продакшен использование Objc за пределами мака
                    Ответить
                • Кстати, мож тебе будет интересно:
                  https://opensource.apple.com/source/objc4/objc4-723/
                  Ответить
                  • оу
                    ну-тоис можно под винду собрать
                    Ответить
                    • Под винду лучше попробуй https://github.com/Microsoft/WinObjC/

                      А то я не уверен, что код по ссылке выше соберётся даже на текущей макоси. Там вроде в notes Леопард упоминается. Но поразбираться можно. Есть NSObject даже
                      Ответить
                      • Не хочу.

                        ObjC не мой любмый язык, а пытаться писать на нем под винду это какое-то анальное извращение имхо

                        зы: вы только не подумайте что я хочу сказать что ObjC говно. Для своего времени он был очень прогрессивным, и многие вещи (вроде месседжей вместо вызова методов) мне даже нравятся
                        Ответить
                        • Да говно-говно. С точки зрения пользователя языка какая разница, какая у тебя диспетчеризация под капотом? (пока оно не тормозит ессно)
                          Ответить
                          • Можно динамическую хрюкотень делать типа делегирования в одну строчку, сохранения комманд и выполнения их потом, сериализации дешевой, паттерна "комманда" (undo, redo), в рантапйме спрашивать поддерживается-ли какой-то месседж (как рефлексия почти) итд.

                            Все это smalltalkство активно используется у скриптовихов (Ruby тут чемпион, то и Python тоже балуется) и ObjC единственный кто так умеет из НЕ скриптовых мейнстримов
                            Ответить
                            • > типа делегирования в одну строчку
                              - не понял
                              > сохранения комманд и выполнения их потом
                              - везде можно, где функции это first class citizens, или я не понял (2)
                              > сериализации дешевой
                              - g Codable
                              > в рантапйме спрашивать поддерживается-ли какой-то месседж (как рефлексия почти) итд.
                              - а вот это вообще вонючее говно...
                              Ответить
                              • >>- не понял
                                Получаешь message и сразу же пересылаешь ее делегату. Попробуй так сделать в java, например: тебе придется явно каждый метод так описывать.

                                >> везде можно, где функции это first class citizens
                                Тебе же не function передают, а дергают метод. Ты просто получаешь message и ее аргументы, кладешь в коллекцию и потом дергаешь.

                                >>Codable
                                Причем тут это?

                                >>- а вот это вообще вонючее говно...
                                Ну именно на этом и сделаны делегаты же:
                                если мой делегат поддерживает message foo, то я ему ее передаю.

                                Хотя того же эффекта можно добиться через интерфейсы (протколы) с дефалтными пустыми реализациями
                                Ответить
                                • > Получаешь message и сразу же пересылаешь ее делегату.
                                  - forward invocation что ли?

                                  > Причем тут это?
                                  - пример дешёвой сериализации в языке без рантайма.

                                  > Хотя того же эффекта можно добиться через интерфейсы (протколы) с дефалтными пустыми реализациями
                                  - в Obj C нет дефолтных реализаций, есть @optional.

                                  > Ну именно на этом и сделаны делегаты же:
                                  - слава богу, и те и другие костыли в Свифте закопали. Правда, пока только наполовину...
                                  Ответить
                                  • >>- forward invocation что ли?
                                    Например, да. Пример: ты реализуешь протокол foo. В нем 94 метода.
                                    Ты хочешь получить делегата в конструктор (init или как там), сохранить его в поле и 93 метода передать ему. А один выполнить сам.

                                    В ObjC это делается легко. В Java очень сложно. В Kotlin завезли сахар и стало легко. В C# хз как с этим: раньше было плохо очень, может уже лучше.

                                    >>- в Obj C нет дефолтных реализаций, есть @optional.
                                    Я помню, я имел ввиду что это можно решить с помощью другого инструмента тоже.

                                    В Java 8 и Kotlin есть дефолтные имплементации в интерфейсах (протоколах, в терминах ябла).

                                    >>- слава богу, и те и другие костыли в Свифте закопали
                                    Как же там делегаты работают?
                                    Ответить
                                    • > протокол foo. В нем 94 метода.
                                      - я понимаю, что метафора, но ёб же вашу мать!

                                      > Ты хочешь получить делегата в конструктор (init или как там), сохранить его в поле и 93 метода передать ему. А один выполнить сам.
                                      - ну да, только я не могу сходу придумать, где бы мне это понадобилось. А ты?

                                      > Как же там делегаты работают?
                                      - что значит как?) Так же и работают. Тебе ничто не мешает накостылить id<BeautifulProtocolWith321OptionalMetho ds> и потом ебошить respondsToSelector. Даже в Свифте.

                                      Но лично я делаю протоколы на 10 сигнатур максимум и, если нужно, затыкаю часть пустой default implementation, но очень редко.
                                      Ответить
                                      • >>ну да, только я не могу сходу придумать,
                                        Огромное количество юзкейсов (см рефакторинг "замена наследования делегированием"). Кеш, прокси, логирование, проверка пермишеннов.

                                        >> default implementation,
                                        То-есть твой класс наследует несколько протоколов с пустыми имплементациями, и потом переписывает нужные? Ну, это тоже ок.
                                        Ответить
                                        • Если ты про https://refactoring.guru/ru/replace-inheritance-with-delegation, то это больше вопрос религии. Там уже и SOLID в ход пошёл. Ну то есть, когда у нас случились протоколы на 94 метода, мы про SOLID почему-то не вспоминали, а потом резко начали.

                                          Кстати, тут тоже неплохо могут помочь default implementation, кмк. В общем, как не посмотри, а в Свифте всё то же, только лучше!
                                          Ответить
                                          • Во-первых многие языки не могут в множественное наследование. Им физически не быть фасадом для двух реализаций без кучи бойлерплейта. Во-вторых наследование вообще попахивает говном обычно, и код действительно получается чище когда у тебя финальный класс делегирует вызовы другому финальному классу без трех оверврайтов.

                                            >>на 94 метода
                                            Ну пускай на 10 методов. Все равно ручной оцтой.

                                            >>Кстати, тут тоже неплохо могут помочь default implementation,
                                            Могут, но в той же Java не бывает множественного наследования и если у тебя не два интерфейса(протокола) с дефалтными импелементациями а именно два класса то ты все равно в жопе.

                                            Я верю что в свифте это решили еще более элегантно.

                                            Я лишь говорю что на момент моего знакомтства с ObjC (а это был год так 2011й) ObjC умел то, что не умели на Java ни C#.
                                            Ответить
                                            • > Во-вторых наследование вообще попахивает говном обычно, и код действительно получается чище когда у тебя финальный класс делегирует вызовы другому финальному классу без трех оверврайтов.
                                              - зачем тебе делать override, если имплементация не меняется? Если класс-родитель держит какое-то состояние, не пойдёт ли всё по пизде с таким подходом?

                                              > но в той же Java
                                              - я не знаю, почему в этой беседе так часто фигурирует слово "Java", мне насрать на джаву, чувак!

                                              > ObjC умел то, что не умели на Java ни C#
                                              - ок. На мой взгляд, у Obj C была другая (ныне немного забытая) особенность, которая опирается на message dispatch и которая в начале 90-х действительно была революционной: распределённое выполнение. Отправляешь мессадж, а где его поймают и обработают тебе уже неинтересно: может, на этом компе, может, на соседнем, а, может, на ноде на атомном ледоходе, пробивающем себе путь в Арктике. Романтичная идея, разбившаяся о суровую реальность
                                              Ответить
                                              • >>зачем тебе делать override
                                                Я могу интерсептнуть ее чтобы залогировать или проверить пермишен, например.

                                                >>мне насрать на джаву, чувак!

                                                Чтобы понять почему messages это хорошо надо понимать как бывает плохо (как в джаве).

                                                А ты говоришь только как в ObjC и как в Swift, и я вполне верю что в Swift оно лучше.

                                                >>распределённое выполнение.
                                                Да, и это тоже.

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

                                                Всё можно представить как акторы, посылающие друг другу messages (привет Эрлангу).

                                                В общем это древний флейм про smalltalk-based vs simula-based.


                                                ps: хотя есть и костыли конечно, тяжелое наследие обратной совместимости с сями: это бесконечные собачки для NSString, для NSArray, чтобы не совпасть с сями случайно итд
                                                Ответить
                                                • > бесконечные собачки ... для NSArray
                                                  - о чём речь? String literal? "C" здесь ни при чём
                                                  Ответить
                                                  • Си именно что причем: Во всех языках практически строковый литерал выглядит как строка в кавычках. В си он означает массив чаров и чтобы не этим не клашиться ObjC пришлось сделать @"My String".

                                                    Так же во многих языках есть литералы для массивов. Есть они и в си, но в Objc чотбыне клашиться с сями пришлось сделать
                                                    @[ ];

                                                    И наконец есть литералы для NSNumber: @42

                                                    зы: а, я понял в чем дело: такие литералы есть в C# и Java. Так что я , вероятно, опять о своем.
                                                    В C++ для правильных строк литералов нет
                                                    Ответить
                                                    • Так что если в новом стандарте C++ захотят заюзать @ для какой-нибудь своей хуйни, это может что-то cломать в Objective-C++, и там уже не будет поддерживаться новый стандарт C++.
                                                      Ответить
                                                    • Для массивов, словарей и NSNumber'ов литералы появились году эдак в 2012. До этого никого 20 лет сишка не мучила :)
                                                      Ответить
                                                      • Ну NSString то всегда был:)

                                                        А NSArray как был без литералов? Там Vararg и Null-terminated?
                                                        Типа

                                                        [NSArray arrayWithObjects:@"Petux",@"Korochko", nil] ?
                                                        Ответить
                                                        • Типа того. Кстати, как бы [] "клашился" с сями? Я не помню, но разве в сишке можно проинициализировать массив через [1, 2, 3]? Там не фигурные скобки?
                                                          Ответить
                                                          • Фигурные, но обычные скобки там указывают на массив.
                                                            Ответить
                      • Такая вот хрень есть http://cocotron.org/
                        И есть форк от разрабов Darling https://github.com/darlinghq/darling-cocotron
                        Ответить
                        • >>implements a usable amount AppKi

                          Не звучит как очень вот уж production ready:)
                          Ответить
                        • А еще был apportable, но его потом втихую выкупил гугл и оно почему-то закрылось
                          https://venturebeat.com/2016/08/18/google-secretly-acqui-hired-mobile-app-development-startup-apportable/

                          https://wayback.archive.org/web/20171216093825/http://www.apportable.com:80/

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

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

      Если б Страуструп делал плюсы несовместимыми с си (и по синтаксису и по семантике), это сраное говнопорождение б тупо не взлетело.
      Ответить
    • Проник в твоё анальное отверстие.
      Ответить
    • Я всё не могу понять, что ты предлагаешь взамен? Писать на Coq, екстрактить в сишку?
      Ответить
      • Ну если пытаться делать все идеально, то нужен некий ЯП для описания аппаратуры (регистров, набора инструкций и прочих таких аппаратных ньюансов. Притом желательно чтоб этот язык подходил как для того, чтоб им можно было описать 8-битные AVR, так и для Сетунь с тритами, ПЛИС, квантовые компьютеры, dataflow, GPU и проч.). Потом сделать другой ЯП, предназначеный для описания синтаксиса и семантики какого-либо ЯП. Потом надо создать специализатор формального описания языка под целевую платформу. И если такому специализатору подать на вход описания языка Си и например описание Сетуни как платформы, этот специализатор должен чего-то там накостылить, но все ж заимплементить язык Си под Сетунь, ну понятно что типы в каноничном Си состоят из битов, потому что есть двоичные сдвиги и все такое, 8-битные char придется запихивать в триты, вообще по-хорошему генератор компилятора для такой платформы должен выдать варнинг, что тут на Сетуни нет битов... и должны быть средства, позволяющие создавать описания для таких языков, которые требуют доказательства корректности...

        Короче, я ушел в дебри. По-моему надо смотреть в сторону DSL/eDSL, вот например https://ivorylang.org/ivory-introduction.html https://leepike.github.io/Copilot/

        Ну и надо развивать средства верификации, теоремы доказывать там, зависимые типы. Вот например современные браузеры, которые ПОГОЛОВНО написаны на C++ и количество RCE уязвимостей под эти самые браузеры. И года не проходит, чтобы в каком-нибудь (ЛЮБОМ) популярном браузере не обнаружили RCE.
        А еще эти блядские уязвимости Meltdown и Spectre, основанные на тайминг-атаках, которые вообще хер пойми как отловить на этапе проектирования. В общем всему жопа и всё говно. Надо писать свой язык и проектировать свой процессор.
        Ответить
        • > И если такому специализатору подать на вход описания языка Си и например описание Сетуни как платформы

          Ты в курсе, что ты только что придумал GCC, который в обе стороны является бэкендом (для архитектур и для языков)? И кстати, угадай, какой главный язык, для которого используют gcc?

          Ты сам ответил на свой вопрос :)
          Семь километров — не крюк, j123123
          Ответить
          • Только вот GCC почему-то не умеет компилировать Verilog под FPGA. Недостаточно универсально
            Ответить
            • > Verilog
              Борманд, залогинься

              > не умеет
              Но ничто же не мешает реализовать для гцц эту платформу и этот язык? Ты только что хотел целую систему делать, я показал, что система уже есть, осталась меньшая часть работы. Можешь реализовать.
              Ответить
              • Для гцц не смогли даже реализовать толковый кодогенератор под стековую машину (текущий рассчитан на регистровую). Когда пытались генерировать байткод для JVM и CIL, просто тратили меньше сил столкнулись с трудностями.

                The hard part is RTL (Register Transfer Language). This part of gcc is hard-wired to generate code for register-based CPU's such as i386, PPC, Sparc, etc. RTL is not designed for generating code for stack-based abstract machines such as IL.

                Also, RTL loses a lot of the type and code structure information that IL needs in the final output file. By the time RTL gets the code, information about whether a value is an integer or an object reference is mostly lost. Information about the class structure of the code is lost. This information is critical for correct compilation of C# to IL.

                But hang on a second! Gcj, the Java back-end for gcc, does stack machines! Why not do something like that?

                Err ... no it doesn't. The Java bytecode stuff in gcj is not organised as an RTL back-end.

                When gcj compiles Java, it performs parsing and semantic analysis in the front-end, like the other supported languages. Then the parse tree is sent in one of two different directions.

                If gcj is compiling to native, the parse tree is handed to the RTL core of the compiler, and it takes over.

                If gcj is compiling to bytecode, the parse tree is handed to a completely separate code generator that knows about Java bytecode.

                Because gcj does NOT implement a bytecode RTL back-end for gcc, it cannot compile C, C++, etc down to bytecode. Java bytecode is a special case that only works for the Java front-end.
                Ответить
                • (продолжение)
                  But what about egcs-jvm? Doesn't it compile C to Java bytecode?
                  It's a hack. The code that it generates is horrible, and does not conform to the usual conventions that the JVM requires. If one compiled Java code using this back-end, it wouldn't work with normal Java code due to the differences in calling conventions and what-not.

                  The biggest problem that the author of egcs-jvm he had was trying to work around the register machine assumptions in the code. The result wasn't pretty. He has said that it would be easier to throw the JVM away and invent a register-based abstract machine than try to make gcc generate efficient stack machine code.

                  Isn't there a gcc port to the Transputer, which is stack-based?
                  Yes there is, for an older version of gcc (2.7.2). The source can be found here.

                  It appears to compile the code to a pseudo-register machine, and then fixes up the code to be stack based afterwards. It takes advantage of some register stack features in gcc that egcs-jvm didn't use.

                  The Transputer is still a traditional CPU despite being stack-based. The gcc port puts pointer values into integer pseudo-registers, which would violate the security requirements of IL.

                  The i386 gcc port uses a regular set of registers for integer/pointer values, and a register stack for floating point values. The Transputer port uses two register stacks: one for integer/pointer values, and the other for floating point values. It may be possible to use three register stacks for IL: one for integer values, another for pointer values, and a third for floating point values.

                  However, this still may not give a useful result. This fixes the security problems for the pseudo-registers, but it doesn't fix the security problems for memory. RTL assumes that main memory is a flat, untyped, address space, where any kind of value can be stored in any word. Partitioning main memory into separate types may not be possible without a rewrite of RTL.
                  Ответить
                  • Текст взят из проекта Portable.NET (DotGNU) — предшественника Mono.

                    Verilog же предназначен не для регистров и не для стека, а вообще не для процессоров. Для него все внутренности придётся делать с нуля.
                    Ответить
                    • Можно сделать такой промежуточный формат который одинаково хорошо превращался бы в stack bases и в registry based?

                      Кстати, llvm registry based что нехарактерно в целом для виртуалок
                      Ответить
        • > Надо писать свой язык и проектировать свой процессор

          Это да, но не из необходимости, а чтобы фофан и чтобы потом кайфово захайриться куда-нибудь
          Ответить
      • Может ты хочешь сказать "Бьёрн Страуструп создал С++ 36 лет назад, и он до сих пор востребован и пользуется популярностью у разработчиков, потому что взамен ничего лучшего не придумали" ?

        Ну нет же, D и Rust по-моему объективно лучше C++ в его нише. Но это тоже какое-то говно.
        Ответить
    • C++ нинужен
      давайти все писать на джаваскрипте, уже многие так делают
      Ответить

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