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

    0

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    24. 24
    25. 25
    26. 26
    27. 27
    28. 28
    29. 29
    #include <iostream>
    
    class Pituh {
    public:
        static void SetInstance(Pituh* pet) {
            Instance_ = pet;
        }
    
        static Pituh& Instance() {
            return *Instance_;
        }
    
        void kok() {
            std::cout << "kok" << std::endl;
        }
    private:
        static Pituh* Instance_;
    };
    
    #define KOK Pituh::Instance()
    
    Pituh* Pituh::Instance_ = nullptr;
    
    
    int main() {
        Pituh pet;
        KOK.SetInstance(&pet);
        KOK.kok();
    }

    Какой багор )))

    Запостил: 3_dar, 26 Августа 2022

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

    • Ну и в чем багор? Разве что если забыть сделать SetInstance, то можно будет вызвать nullptr.kok(), что по стандарту UB.
      Ответить
      • раскрой двадцать седьмую строку

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

              Санитайзер что ли включен?
              Ответить
              • > Санитайзер что ли включен?

                Ага, с -fsanitize=undefined действительно ловится.
                Ответить
                • А зачем цитировать полностью предыдущее сообщение? Тем более своё. Если nugop_cpakep потрёт, то потрёт оба.
                  Ответить
              • Нет, просто debug сборка без санитайзеров.
                Ответить
                • Странно, у меня только с санитайзером ловит такое. А какой конпелятор?
                  Ответить
                  • Шланг
                    Ответить
                    • Тоже не ловит без опции. Может у тебя глобально какие-то настройки накручены?
                      Ответить
                • зачем нужна дебаг сборка без санитайзера?
                  Ответить
          • Я жеж написал
            раскрой строку 27

            что вернет Instance?

            на строке 10 будет бадабум
            Ответить
            • Ох да. Такое действительно сложно заметить.

              Хотя при разыменовании указателя в ссылку компилятор не обязан проверять на ноль, так что такое только в дебаге может выплыть, где доп.проверки вместо перформанса.
              Ответить
              • >при разыменовании указателя
                нулевой указатель это УБ при попытке его разыменовать (ну или хардварная защита процессора в случае, если компилятор не атловил)

                > в ссылку

                а что, есть какой-то особый случай: разыменовывание в ссылку?

                Алсо, ссылка нулевой не бывает
                Ссылка на нул это тоже УБ
                Ответить
                • >а что, есть какой-то особый случай: разыменовывание в ссылку?
                  Наоборот. Конечно, свинтаксически и семантически ссылка и указатель - разные вещи, но... мы же всё понимаем, и на самом деле это одно и то же. Так что разыменование в ссылку - это вообще не разыменование, там ничего не происходит. Ну разве что в дебаг-версии вставлена дополнительная проверка на null.
                  Ответить
                  • Верно.

                    При превращении указателя на нул в ссылу можно ничего не разыменовывать на самом деле, потому в реальной жизни может ничего и не упасть, но поскольку по стандарту это УБ, то компилятор может понять, что там null, и просто выкинуть код
                    Ответить
                    • Ещё больший пиздец — нулевых ссылок быть не может. Поэтому, если ты, питух, запихал туда нулл, то компилятор может нассать тебе в рот и выкинуть все твои проверки, которые ты добавил потом:
                      extern int i;
                      
                      void do_shit(int& x)
                      {
                          if (&x == nullptr)
                              i = 4;
                      }
                      
                      void do_shit2(int& x)
                      {
                          if (&x != nullptr)
                              i = 4;
                      }
                      ////
                      do_shit(int&):
                              ret
                      do_shit2(int&):
                              mov     DWORD PTR i[rip], 4
                              ret
                      Ответить
                      • ога

                        мну и написал выше
                        >
                        Алсо, ссылка нулевой не бывает
                        Ссылка на нул это тоже УБ
                        >
                        Ответить
                • Эти ваши nullable pointers - ублюдочное порождение model flat на штеудах.
                  Ответить
                  • Что-то я даже задумался, как без нуллов обходиться.
                    Ответить
                    • g: the billion dollar mistake
                      Ответить
                    • Майки бы предложили знаковые пойнтеры, -1 значит нет такого адриска.
                      Ответить
                      • Это чтобы половину адресного пространства можно было выкинуть?
                        Ответить
                        • а не вы ли все тут мне рассказывали как плохо, что индексация массиов unsigned кое-где, и что лучше бы она была signed, как в жабе?
                          Ответить
                          • Точно не мы, т.к. мы не джавамены.
                            Ответить
                            • точно было на ГК от Тараса.
                              аргумент был в пользу обратново обхода моссива
                              for (int i=N-1; i >= 0; i--) { ... }

                              не могу найти тот коментарей гуглеца только новае https://govnokod.ru/27255#comment609585

                              P.S. Привет, ГК. Рада была заглянуть. Ну тогда, я надеюсь, до следующей встречи через несколько месяцев!
                              Ответить
                        • Эту половину можно использовать под коды ошибок.
                          -1 — Нет такого указателя
                          -2 — Память недоступна
                          -3 — Недостаточно привелегий.
                          ...
                          -418 — это, вообще-то, чайник.
                          Ответить
                      • Битовое представление nullptr не имеет значения, оно и не обязано быть нулевым числом. Вопрос в том, есть оно или нет.

                        Как я понял, нужно было сделать, чтобы нуллябельность задавалась явно, т.е. по умолчанию указатель пустым быть не может.
                        Ответить
                        • такой укозатель называется "cccccccссссылка"
                          Ответить
                          • Смотря в каком языке, может быть разная терминология. В C# и Java бывают и нулевые ссылки, а в С++ ссылка - это не просто ненулябельный указатель, есть пополнительные ограничения - нужно сразу инициализировать и дальше менять значение нельзя.
                            Ответить
                            • Я говорю о С++, конечно. Анскилябрные недоподелки нельзя обсуждать всерьез.

                              В ЙАЖА, кстати, ссылка называется то ссылкой, то указателем: они никак не могут определиться. В C# это, кажется, всегда ссылка. В перле -- тоже

                              >нужно сразу иници
                              Это и проистекает из невозможности иметь нуль.

                              А еще ссылка удобно обмазана сахаром, чтобы не писать везде &, * и ->
                              Ответить
                              • >>нужно сразу иници
                                >Это и проистекает из невозможности иметь нуль.
                                Не вижу связи. В шарпе бы проистекало, а в С++ можно было бы сделать и мутабельные ссылки.

                                class C {
                                  int m_i;
                                  Svinia &m_svinia;
                                public:
                                  C() {
                                    // <- здесь m_i и m_svinia не определены
                                    m_i = 69;
                                    m_svinia = ...;
                                  }
                                };

                                (предположим, мы не можем по каким-то причинам инициализировать через двоеточие)
                                Ответить
                                • > // <- здесь m_i и m_svinia не определены

                                  то есть обращение к ним это УБ, верно?

                                  Ты не можешь занулить ссылку по умолчанию: это будет лишнее дейстие, не бесплатное
                                  Ответить
                                • > m_svinia = ...;
                                  Что должна вызывать эта строка?
                                  Ответить
                                  • Недоумение.
                                    Ответить
                                  • Побуду адвокатом дъявола:

                                    Если это первое обращение к ссылке, то инициализация

                                    Если второе, то ошибку компиляции

                                    Как final в ЙАЖА.

                                    ps: любые сомнения трактуются в пользу ошибки компиляции
                                    Ответить
                                    • > ошибку компиляции
                                      Только есть проблема: присвоение неконстантной ссылке, благодаря «А еще ссылка удобно обмазана сахаром, чтобы не писать везде &, * и ->» — это полностью валидная операция:
                                      #include <cstdlib>
                                      #include <cstdio>
                                      
                                      struct Svinina {
                                          int zhir;
                                      };
                                      
                                      struct C {
                                        int m_i;
                                        Svinina &m_svinina;
                                        
                                        C(Svinina & svin): m_svinina(svin) {
                                          // <- здесь m_i и m_svinia не определены
                                          m_i = 69;
                                          m_svinina = Svinina(55);
                                        }
                                      };
                                      
                                      int main() {
                                          auto svin = Svinina(10);
                                          auto c = C(svin);
                                          std::printf("zhirnota: %d\n", svin.zhir);
                                          return EXIT_SUCCESS;
                                      }

                                      https://gcc.godbolt.org/z/e4Ef48PfM
                                      Ответить
                                      • и правда


                                        Если я могу прозрачно вызвать по ссылке оператор плюс, то почему не могу вызвать присваивание?)

                                        Ну по идее можно конечно вызывать присваивание второй раз, но тогда конечно будет ад (а еще это не отвалидировать статически нормально)

                                        Тогда пускай Стив со своей выдумкой сам разбирается
                                        Ответить
                                        • > Ну по идее можно конечно вызывать присваивание второй раз, но тогда конечно будет ад (а еще это не отвалидировать статически нормально)
                                          На это и был расчёт, да:
                                          struct Svinina {
                                              int zhir;
                                          };
                                          
                                          auto staticheckaya_svinina_1 = Svinina(44);
                                          auto staticheckaya_svinina_2 = Svinina(55);
                                          
                                          struct C {
                                            int m_i;
                                            Svinina &m_svinina;
                                            
                                            C() {
                                              // <- здесь m_i и m_svinia не определены
                                              if (rand() % 2 == 0) {
                                                  m_svinina = staticheckaya_svinina_1 ;
                                              }
                                              m_i = 69;
                                              m_svinina = staticheckaya_svinina_2 ;
                                            }
                                          };
                                          Ответить
                                          • а как это будет работать в Кокок/ЙАЖА для final полей?
                                            Ответить
                                            • Им похуй, судя по всему:
                                              class MyClass {
                                              
                                                  val s: String
                                              
                                                  init {
                                                      if ((0..1000000).random() == 0) {
                                                      	s = "value"
                                                      }
                                                      
                                                      s = "other_value"  // Error: Val cannot be reassigned
                                                  }
                                              
                                              }
                                              Ответить
                                              • то есть у кокоджамбы s будет нулом? сломался нул сейфти?

                                                а нет

                                                просто не скомпилица, и все

                                                попробуй, убери other value
                                                Ответить
                                                • Не, они наоборот делают:
                                                  class MyClass {
                                                  
                                                      val s: String  // Error: Property must be initialized or be abstract
                                                  
                                                      init {
                                                          if ((0..1000000).random() == 0) {
                                                          	s = "value"
                                                          }
                                                         
                                                      }
                                                  
                                                  }
                                                  Ответить
                                                  • С каких пор ты на Jawa-параше прогаешь?
                                                    Ответить
                                                    • Я не прогаю, просто на работе приходится иногда поглядывать на кококо-проекты.
                                                      Ответить
                                      • Ты сохраняешь свинью со стека, такую нельзя жрать же?
                                        Ответить
                                        • он сначала пихае туда внешнюю свыню, а затем замещает ее стековой

                                          Я думаю, что если он ловко переопределит оператор присваивания, то беды не случится

                                          чото я затупил: а по умолчанию же присваивание просто перезапишет свыню для тупых типов?
                                          Ответить
                                          • > чото я затупил: а по умолчанию же присваивание просто перезапишет свыню для тупых типов?
                                            Да.
                                            Ответить
                                        • В этом и смысл: у меня в m_svinina лежит ссылка на свинью из main(). Этой ссылке я присваиваю другую свинью — и, поскольку ссылки полностью прозрачны, этим я просто перезаписываю значение свиньи из main() (обратите внимание, какая свинья передаётся в printf()).
                                          Ответить
                                          • короче ты жир 10 поменял на жир 55 просто
                                            Ответить
                                          • напоминает кстати известный прикол типа
                                            petuh.kurochka() = 42;

                                            тоже работает благодаря возврату ссылки
                                            Ответить
                                          • Теперь дошло. КАКОЙ БАГОР )))
                                            Ответить
                                    • Ну да, тут я что-то намудрил. Тогда придется отличать присваивание ссылки от присваивания объекта, что-то типа
                                      m_lubimaya_svinia =&= condition ? Mashka : Zorka;
                                      В общем, лучше не надо.
                                      Ответить
                                      • =()=
                                        Ответить
                                        • Вот кстати в перле семантика примерно как у указателей, но называются они ссылки

                                          Там, правда, есть сахар чтобы не разыменовывать вручную при обращении к полям (как и в говне)
                                          Ответить
                                • ps:

                                  Вообще, есть такой философский момент, Страус его пояснял в своей книге.

                                  Указатель это отдельная независимая сущность. Объект.
                                  А ссылка это не сущность. Не объект, это просто способ обращения к объекту. Ссылки не существует без объекта, на который она указывает.

                                  и думать о ней нужно именно так: ты не со ссылкой работаешь, ты работаешь с объектом по ссылке.

                                  Указатель сам по себе
                                  А ссылка это тень от объекта)

                                  тут и далее: объект не ООПарашна, а объект в сишном понимании: некий артефакт в памяти
                                  Ответить
                    • А никак. От включения в множества значений "не определено" не избавиться никак, если модель предполагает возможность этого "не определено". Заворачивание в дополнительные обёртки никак не спасает от ситуации, когда программист уверен что оно здесь будет определено, а на деле не определено.
                      Ответить
                      • избавиться можно, но как реализовать циклический буферок?
                        Null object?
                        Ответить
                      • > Заворачивание в дополнительные обёртки никак не спасает от ситуации, когда программист уверен что оно здесь будет определено, а на деле не определено.

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

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

                          Ты получаешь Result, и обязан его пттрнматчнуть. Там либо ненулевой результат, либо залупа конская

                          В самой яже никак тк нет нулсейфти
                          Ответить
                          • > В самой яже никак тк нет нулсейфти

                            Ты что, на яже напрограммировал?! Ой мудак... И maybe весь засрал. Иди под haskell мойся! Чтобы без нуллов был!
                            Ответить
                        • ну и сделает он в этой ветке эррор с пометкой "этого не может быть". и грохнется всё с ним, ровно так же, как с нпе.
                          Ответить
                          • файк, а ты точно знаешь, что такое паттерн матчинг?

                            что там грохнется, если оно тупо не скомпилица?
                            Ответить
                            • > что там грохнется

                              там недавно был мемес про четыре стадии улучшения кода с эксепшенами на хаскелле, который вернулся к эксепшенам

                              Вы мне сейчас про то что там в промежуточных функциях будет case Just -> ... и Nothing -> Nothing. Я вам про то, что если программисту пришло Maybe и там по его мнению обязано быть значение - например, потому что в общем случае может вернуться Nothing, а в частном Just, и выше по коду отсекаются все другие случаи - то мы находимся в ровно той же ситуации. Здесь у программиста всего два варианта:

                              - Сделать вид, что Nothing не может существовать, например кинув туда тот самый эррор
                              - Сделать код, который допускает Nothing и не следует тому, что от него требуют

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

                                Это из серии
                                if (petuh == 42) {
                                   throw Error("быть такого не может вообще никогда")
                                }
                                Ответить
                                • Смотри, я всегда ношу из одного места в другое один и тот же пример, в основном правда объяснять в чём проблема с потерей источника проблемы Maybe-alike не-всегда-монадными обёртками

                                  - На увожаемом микросервисном веб-портале есть реклама
                                  - Для каждой страницы может быть или не быть свой баннер
                                  - Оно пропускает через функционал а/б тестирования, которое может заменить или убрать баннер
                                  - У платных падпищеков реклама отключена
                                  - Но на главной баннер должен быть всегда вне зависимости от фильтров выше

                                  Мы получаем цепочку типа (нет, не ждите от меня хаскель-синтаксиса)

                                  adService.getBannerFor(route)
                                  .flatMap(experimentationService.mapBanne r)
                                  .filter(banner -> userService.showBannner(banner, route))

                                  Фронтенд-петух или гейтвей-петух пишет обработчик главной. Согласно контракту, на главной баннер быть обязан, но если кто-то из вышестоящих петухов проебался, то он получит неожиданное поведение. В этом случае он не пидор. Но эта ситуация сама по себе уничтожима только созданием отдельного getBannerForHome() с гарантированным тем или иным образом значением, что применимо только к ограниченному количеству ситуаций.
                                  Ответить
                                  • Если кто-то наверху проебался, то он нарушил контракт

                                    Наш фронтэнд питух ничего про это знать не должен.

                                    Если производитель процессора проебался, и при обращении к валидной памяти бросил исключение, то я не обязан это обрабатывать

                                    Кто нарушил контракт -- тот и пидор
                                    Кто нарушил контракт -- тот и пидор
                                    Кто нарушил контракт -- тот и пидор
                                    Кто нарушил контракт -- тот и пидор
                                    Ответить
                                  • > Согласно контракту, на главной баннер быть обязан

                                    Согласно контракту (устному)...
                                    Напомнило древний мем гейдев.ру про "устный договор": https://gamedev.ru/flame/forum/?id=139100

                                    Дело в том, что если контракты у тебя в коде не выражены в виде типов, то ты неправильно используешь говнады и maybe, и занимаешься карго-культом.
                                    Ответить
                                    • Как надо:
                                      Если какая-то функция не ожидает Nothing "по контракту", то она как аргумент должна принимать не `Maybe x` а чистый `x`. Пусть вызывающий её ебётся с обработкой ошибок (тупо залифтив в монаду, например).

                                      А принимать Maybe и рассчитывать(!) что вызывающий(!) функцию никогда не положит туда Nothing — это оставлять сюрприз тому, кто в будущем вызовет твою функцию где-то ещё. Какой-то постмодернистский уровень ротоёбства.
                                      Ответить
                                      • откуда эта гифка? я думал что из american psycho, но на днях посмотрел, оказалось что дефо там нет в клубных сценах https://twitter.com/hourly_shitpost/status/1564644128981499912
                                        Ответить
                                        • Пиздец, оказалось, существует группа Bale Defoe
                                          Ответить
                                          • кажется, это всего лишь один афродейтротчанин
                                            Ответить
                                      • И толку с этого?

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

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

                                        Разруха, она в головах, не в языке.
                                        Ответить
                                        • > творящая всякую хуйню
                                          так не твори хуйню, ну

                                          Мейби хотя бы заставляет тебя явно сказать: "я творю зуйню" а в говноязычках и этого нет
                                          Ответить
                                        • Пример файка абсурден (если на главной всегда обязан быть баннер, зачем вообще прогонять код, отвечающий за баннер, через A/B тесты и другие проверки? Если же допустить, что это следствие использования какой-то ``абсракции'' в ``фрейворке'', то и на какие-то неявные контракты рассчитывать нельзя: функция обязана делать то, что от неё требует ``фреймворк'').

                                          > И толку с этого?

                                          Функция — это законченная единица кода, то есть то, что можно в теории реюзать.
                                          Если у тебя настолько идиотская бизнес логика, что в каком-то месте нужно творить хуйню, то хуйню в коде надо творить как можно ближе к логическому источнику хуйни.
                                          Ответить
                                          • Я бы ещё добавил, что проверка наличия всех нужных компонентов — это задача автовайринга или его аналога, а не функции, которая рисует страничку. SRP же, ну.
                                            Ответить
                                            • Это у скучных старпёров их SOAPами и WSDL/схемами.


                                              У молодых, динамично развивающихся смузихлёбов, по ресту просто приходит JSON
                                              Ответить
                                    • > устный договор
                                      #define my_nothrow // мамой клянус
                                      
                                      my_nothrow void my_nothrow do_shit_nothrowing() my_nothrow;
                                      
                                      ...
                                      
                                      void do_shit_nothrowing()
                                      {
                                        throw new std::string("Наебал! Наебал!");
                                      }
                                      Ответить
                                      • Потому что С++ не проверяет исключения

                                        в Йажа для чекд исключений такой проблемы нет
                                        Ответить
                                        • Есть другая проблема: британские учёные доказали, что максимум через 3 минуты 52 секунды написания и поддержки списков выбрасываемых исключений даже самый опытный и усидчивый энтерпрайз-разработчик сдаётся и начинает хуярить «public void doShit() throws Throwable».
                                          Ответить
                                          • Checked исключения очень хуевое решение проблемы

                                            Хуево потому, что даже для неприхотливого жаваеба оно настолько вербозное, что просто даже не смешно. Пальцы заболят и будет артрит, если постоянно пользоваться чекд исключениями.

                                            Но с другой стороны, оно хотя бы есть. В некоторых других языках и такого нету.

                                            Разумеется, Maybe в охулион раз лучше решает ту же самую проблему
                                            Ответить
                                            • Maybe на самом деле не предназначено для замены исключений, checked or otherwise. Оно подходит исключительно для замены nullable, т.е. для случаев, когда отсутствие чего-то полностью ожидаемо, и (важно!) ты никогда не собираешься искать, где и когда оно обнулилось, т.к. хуй найдёшь.
                                              Ответить
                                              • Checked исключения тоже для ситуации, когда отсутствие ожидаемо. А вот наличие у них стектрейса (для поиска мерзавца) это глупая деталь реализации кмк.
                                                Ответить
                                      • Это письменный. Можно даже сказать смарт-контракт в блокчейне git.
                                        Ответить
                              • - вернуть Nothing, пусть голова болит на уровень выше.
                                Ответить
                                • и так до самого верху

                                  А наверху написать: "Произошла неизвестная ошибка, а больше мы ничего сказать не можем, потому что контекст проебан. Можете попробовать sfc /scannow, нам однажды помогло"
                                  Ответить
                              • > пришло Maybe и там по его мнению обязано быть значение

                                То его мнение никого не волнует. Coq/Agda ему ещё ошибкой по жопе дадут, если он своё мнение попытается высказать.

                                > и выше по коду отсекаются все другие случаи

                                Пусть "выше по коду" передаёт нам чистое значение, если там действительно все случаи отсечены. Если ты такой молодец и обработал Nothing — работай с чистым значением.

                                > Здесь у программиста всего два варианта:

                                Пиздец. Здесь всего один вариант: сделать дальнейшие вычисления чистыми и за-fmap-ить их в Maybe. Короче, я не знаю, откуда ты берёшь свои мемесы, но смени дилера. Твой в haskell вообще не в зуб ногой.
                                Ответить
                          • Ты что, на яже напрограммировал?! Ой мудак... И maybe весь занулил. Иди под haskell мойся! Чтобы нуллсейфным был!

                            P.S. Копипаста была заготовлена как раз для этого ответа.
                            Ответить
          • >Потенциальное или реальное?

            меня всегда пугают такие фразы

            --Чувак, у тебя тут гонки по мемори модел
            --Ой, да в реальной жизни никогда не случится

            --Чувак, у тебя тут UB по стандарту
            --Ой, да в реальной жиз..

            а потом люди погибают
            Ответить
            • Я верю в человечество, поэтому буду считать, что под «потенциальным UB» Steve_Brown имел в виду UB, возникающее при определённых условиях, которые в реальной жизни не встречаются. Например:
              std::array<int, 3> koorica = {3, 2, 1};
              int i{};
              std::cin >> i;
              std::cout << koorica[i] << std::endl;

              — здесь наступление UB возможно, но происходит оно не для всех веток исполнения: если пользователь вводит только 0, 1 или 2 — программа полностью валидна и корректна. Это можно считать «потенциальным UB».
              Ответить
              • Я думаю под потенциальными UB он имеет в виду те, которые компилятор не использует. Например, запись-чтение из разных полей union у нас успешно работает в проде, хотя это UB.
                Ответить
                • >успешно работает в проде,
                  вы, главное, компилятор не обновляйте
                  Ответить
              • понятно

                хотя за неочищенный пользовательский ввод всё равно нужно бить по рукам
                Ответить
      • > неконстантный метод

        Это ты про kok? Нашёл до чего доебаться
        Ответить
      • А как по другому? В реальном коде у меня недефолтный конструктор у петуха.
        Ответить
        • По другому -- в коде на С++ не должно быть "#define"

          Петуха (уж коли он один на всю систему) я бы сделал локальной статической переменной

          нельзя как-то
          Petuh& petuh()  {
           static Petuh p;
          return p;
          }


          или у тебя питух размером с терабайт, и живет в куче?
          Ответить
          • > static Petuh p;
            Однако нужно понимать, что в этом случае компилятору придётся генерировать дополнительный код, гарантирующий потокобезопасную и строго-однократную инициализацию такого петуха. Если ты получаешь петухов миллиард раз в секунду — локальная статическая пельменная может ударить по производительности.
            Ответить
            • А это деталь реализации, или прямо в стандарте написино?

              А если я сделаю глобальную пельменную (она инициализируется вроде до первого запуска первой функции модуля) то компилятору не надо будет каждый раз проверять, что она тнициализирована же?

              static Petuh p; //ой отсосу в случае исключения из конструктора конечно, ну и похуй
              
              Petuh& petuh()  {
              return p;
              }
              Ответить
              • > А это деталь реализации, или прямо в стандарте написино?
                Стандарт гарантирует, что локальная статическая пельменная будет инициализирована строго один раз, даже если её дёргают из нескольких потоков. Про то, как это реализовать, Стандарт не говорит, разумеется, но на практике компилятору придётся вставлять туда какой-то примитив синхронизации.

                > А если я сделаю глобальную пельменную (она инициализируется вроде до первого запуска первой функции модуля) то компилятору не надо будет каждый раз проверять, что она тнициализирована же?
                Не помню, как это реализовано, но не придётся.

                Реальный пример:
                int foo(int x) {
                    static int y = x;
                    return y + x;
                }
                
                static int STATIC_Y = 777;
                
                int bar() {
                    return STATIC_Y;
                }
                
                int baz(int z) {
                    STATIC_Y = z;
                    return z;
                }


                foo(int):
                        push    rbx
                        movzx   eax, BYTE PTR guard variable for foo(int)::y[rip]
                        mov     ebx, edi
                        test    al, al
                        je      .L10
                .L3:
                        mov     eax, DWORD PTR foo(int)::y[rip]
                        add     eax, ebx
                        pop     rbx
                        ret
                .L10:
                        mov     edi, OFFSET FLAT:guard variable for foo(int)::y
                        call    __cxa_guard_acquire
                        test    eax, eax
                        je      .L3
                        mov     edi, OFFSET FLAT:guard variable for foo(int)::y
                        mov     DWORD PTR foo(int)::y[rip], ebx
                        call    __cxa_guard_release
                        mov     eax, DWORD PTR foo(int)::y[rip]
                        add     eax, ebx
                        pop     rbx
                        ret
                bar():
                        mov     eax, DWORD PTR STATIC_Y[rip]
                        ret
                baz(int):
                        mov     DWORD PTR STATIC_Y[rip], edi
                        mov     eax, edi
                        ret
                STATIC_Y:
                        .long   777

                https://gcc.godbolt.org/z/z6KsTr99q
                Обратите внимание, как распидорасило бедную foo.
                Ответить
                • То есть насрали многопоточники, которые мне может и не нужны
                  А КАК ЖЕ "НЕ ПЛАТИ ЗА ТО ЧТО НИИСПОЛЬЗУЕШ"??

                  А вот Мейеру похуй на оверхед
                  https://laristra.github.io/flecsi/src/developer-guide/patterns/meyers_singleton.html
                  instance()
                    {
                      static singleton_t s;
                      return s;
                    } // instance


                  >распидаорасило
                  вижу, вижу guard variable
                  Ответить
                  • Пиздец, то есть так лучше не дела ть? У нас синглтон реализован именно так. Кроме того, что я нахуевертил в сабже.
                    Ответить
                    • Я бы сказал, что лучше делать именно так (по Мейеру). Вряд ли у тебя получится навелосипедить более производительный велосипед, а лишаться потокобезопасной инициализации ради нихуя — такая себе идея.
                      Ответить
                      • Почему ради нихуя? Чтобы не было синхронизационного оверхеда. А инициализацию я сам гарантирую, потому что делаю её перед запуском многопоточной питушни.
                        Ответить
                        • Петя говорит, что оверхед на самом деле настолько мваленький, что можно забить
                          Ответить
                          • Как тогда обеспечить exactly-once инициализацию? Без мьютекса и лока.
                            Ответить
                            • Если у тебя метод вызывается строго из одного потока, то нахрена лечить?


                              Если объект у тебя не кидается исключениями из колнструктора и теюе не нужна ленивость, то можно сделать его статическим нелокальным и сразу на месте инициализировать
                              Ответить
                      • >а лишаться потокобезопасной инициализации ради нихуя

                        Совершенно не очевидно, почему вдруг именно это место надо сделать потокобезопасным

                        На всякий случай? А добавление в вектор у меня потокобезопасное? Не надо ли и его тоже потокобезопасным сделать?
                        Ответить
                        • Потому что RAII. Кресты тебе гарантируют*, что для всякой автоматической пельменной конструктор и деструктор будут вызваны строго по одному разу и упорядоченно. Это один из краеугольных камней крестов.

                          * Без учёта багов в компиляторе и static initialization order fiasco.
                          Ответить
                          • Раииии яяяяя
                            Ответить
                          • ну автоматические пельменные и нельзя из разных потоков трогать (кроме захвата их по ссылке и передачи укозакоза лол, но они уже инициалоизированы к тому моменту), а вот статическая локальная это, конечно, интересный крокодил, и потому такой отсос

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

                    > А вот Мейеру похуй на оверхед
                    Там это в явном виде написано:
                    >>> If control enters the declaration concurrently while the variable is being initialized, the concurrent execution shall wait for completion of the initialization.

                    И считается не оверхедом, но плюсом:
                    >>> Using this pattern guarantees that the single type instance is available at any point during execution, and that it will be properly destroyed. This pattern also insures thread-safe initialization.
                    Ответить
                  • The number of singletons is increasing

                    https://www.bbc.com/worklife/article/20220405-single-shaming-why-people-jump-to-judge-the-un-partnered
                    Ответить
                • Ну, на повторном входе лишними командами выполняются только movzx, test и je. Самое тяжёлое благодаря double-checked lock не исполняется. Хотя, учитывая, что у подобных функций полезная нагрузка обычно только возврат ссылки, даже это будет значительной частью времени исполнения этой функции.

                  Вывод: не дрочи получение инстанса синглтона по 50 раз на строку. Взял ссылку, сохранил, и пользуйся.
                  Ответить
    • зачем ты принимаешь указатель и хранишь указатель а возвращаешь ссылку?

      Боженька наказал тебя за неконсистеность. Возвращал бы указатель -- горя бы не знал
      Ответить
    • > KOK.SetInstance(&pet);
      > return *Instance_;

      Делать «*Instance_» при nullptr в Instance_ — всегда UB, даже если ты просто разместил объяву возвращаешь ссылку, даже если потом зовёшь на ней только static-методы.
      Ответить
    • А вообще были случаи, чтобы кто-то написал на С++ сиглтон, и не получил бы в итоге кусок говна?
      Ответить
      • https://laristra.github.io/flecsi/src/developer-guide/patterns/meyers_singleton.html
        Ответить
        • годно

          почему тогда все пишут свое трехугольное колесо, и обсираются?
          Ответить
      • Ты про JVM?
        Ответить
      • > сиглтон

        А что такого особенного и сложного в этом? Ну типа в Си в отдельном .c файле (в отдельной специальной единице трансляции) объявить некую структуру. Потом сделать одну глобальную статическую переменную с этим вот типом, и в тот же файл насрать каких-то функций, которые с этой глобальной статической переменной какую-то хуйню делают. Ну и все собственно, можно дергать эти видимые снаружи функции, которые только с вот той хуйней и работают. Тут даже кресты нахуй не нужны
        Ответить
        • Так это в Си, а ты попробуй в C++ сделать.
          Ответить
        • Нахуя кстати "синглтон" объявили каким-то там паттерном? Ну т.е. что вообще такого особенного и существенного в том, чтобы была некая хуйня в одном единственном экземпляре на всю программу?
          Может быть давайте тогда еще называть паттерном оператор goto который выпрыгивает из цикла? Или давайте назовем паттерном ситуацию, когда в функцию передается указатель на некую функцию, и та функция потом ее вызывает? По какому критерию что-то там называют словом "паттерн"?
          Ответить
          • Паттерн в том, чтобы делать метод GetInstance, Instance, operator new - в общем как договоритесь (в этом и смысл паттерна).
            Питух видит стандатное GetInstance и сразу помнимает, что это синглтон, а не какая-то мутная поебень.
            Ответить
          • >, когда в функцию передается указатель на некую функцию, и та функция потом ее вызывает?

            Это паттерн "стратегия"
            Ответить
          • Паттерн — очевидное типовое решение типовых проблем. Обычно описывается одной фразой.

            К примеру Медиатор:
            Если есть отношение «многие к многим», его можно превратить в 2 «один ко многим» вставив посредника посередине.

            Всё. Всё остальное — вода и графомания.
            Ответить
            • Опиши визитор одной фразой или флайвейт
              Ответить
              • > флайвейт

                Повторяющиеся неизменяемые части можно хранить отдельно в единственном экземпляре, ссылаясь на них в объектах.

                > визитор

                Выполнение разного кода для разных конкретных типов оперируя над базовым типом через создание нескольких методов для разных типов в классе-посетителе и выбирая нужный через double dispatch.
                Ответить
                • Или даже: делаешь методы для разных подтипов/случаев/хуючаев в классе, отдаёшь его и вызываемый объект сам дёргает тот, который нужно.

                  (покрывает случаи без наследования, типа std::variant в крестах)
                  Ответить
            • > Паттерн — очевидное типовое решение типовых проблем. Обычно описывается одной фразой.

              Тогда к паттерну можно отнести например цикл for. Или while. Или рекурсию. Но почему-то это не называют паттерном. Почему?
              Ответить
              • Рекурсия не относится к поркетированию, это выражение рекуррентного отношения к происходящему.
                Ответить
              • Потому что паттерн — это архитектурное решение, которое может быть выражено различными средствами языка, а цикл for — это просто синтаксическая конструкция.
                Ответить
                • Архитектор нахуй? Спроектируй мне уличный туалет на даче.
                  Ответить
                • Ну вот допустим есть задача "выполнить некий кусок кода много раз с разными значениями некоторых переменных", я могу эту задачу решать через "for", через "while", через "goto", через рекурсию. Задача "вызвать некий кусок кода много раз с разными значениями некоторых переменных" это "паттерн"?
                  Ответить
                • В Лиспе цикл for это архитектурное решение, которое может быть выражено различными средствами языка /green
                  Ответить
                  • В "синглтоне" архитектурности не больше, чем в цикле "for"
                    Ответить
                    • Пиздец ты скучный, не возьмем тебя в чудный мир ООП:)
                      Ответить
                • > архитектурное решение
                  > синтаксическая конструкция

                  Т.е. "паттерн" -- это архитектурное решение, которое нельзя выразить существующей конструкцией конкретного языка?

                  З.Ы. Логично. Если у меня в "ассемблере" нету никаких циклов, то я юзаю паттерн из нескольких инструкций.
                  Ответить
                  • Верно

                    С тех пор, как в языке появились итераторы, необходимость в этом паттерне отпала
                    Ответить
          • Потому что потерна «singleton» еще и «simpleton».
            Ответить
        • А теперь сделай мне созданиеструктуры ленивым, но без лишних проверок на каждое получение
          Ответить
          • > А теперь сделай мне созданиеструктуры ленивым

            А зачем? Нахуя это нужно?

            > но без лишних проверок на каждое получение

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

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

              Потому что в крестах есть конструктор, и создание объекта может оказаться лишним действием

              >А в крестах это как решается?
              Как мы недавно узнали--никак)
              Ответить
            • Можно насоздавать тысячи шаблонных синглтонов
              Ответить
          • Это же нужно структуру в защищенной странице создавать, и обрабатывать page fault...
            Ответить
            • У меня в контроллерах нет никакого "page fault"
              Ответить
            • В контроллере кстати можно сделать так, чтоб любая функция синглтона изначально содержала в себе goto на специальную хуйню, и эта хуйня пусть проинициализирует синглтон и перезатрет этот goto у всех функций синглтона на код, который там обычно должен выполняться, и чтоб потом выполнилась эта пофикшенная функция без goto. Вот это будет реально zero-cost
              Только такую хуйню надо будет на ассемблере херачить.
              Ответить
              • Охуенная идея, прямо духом старого ГК повеяло!
                Въебал плюсю.
                Ответить
              • за самомодифицируемый код пробивали леща еще в моем детстве
                Ответить
                • Угадай, зачем в большинстве системных функций в Шиндовс MOV EDI, EDI в начале?
                  Ответить
                  • Что такое "системных"? Обёртки вокруг сисколов?

                    Кто-то насрал в DI, и надо его почистить?
                    Ответить
                    • > Что такое "системных"? Обёртки вокруг сисколов?
                      Лежащих внутри системных DLL.

                      > Кто-то насрал в DI, и надо его почистить?
                      Нет. Подсказываю: это одна инструкция размеров в 2 байта, не делающая нихуя.
                      Ответить
                      • >Лежащих внутри системных DLL.
                        kernel32? user32? advapi?

                        >нихуя
                        а, я в шары долблюсь, видимо

                        mov, а не xor.

                        Чтобы насрать что-то поверх нее?
                        Ответить
                        • > Чтобы насрать что-то поверх нее?
                          Да, в эти два байта пихается короткий джамп на нормальный джамп, который ведёт на замену этой функции, чтобы обновлять библиотеки прямо в памяти.
                          Ответить
                          • а нахуя такой трамплин? нахуя обновлять?

                            я уж скорее подумал бы про minwin, когда там функция лежит черте где

                            api-ms-win-core-apiquery-l1-1-0.dll

                            вот это всё
                            Ответить
                            • Костылить что-нибудь без ёбли с определением длины инструкции.
                              Ответить
                              • костылить это манку патчить в смысле?

                                муху CC вставлять что ли?)
                                Ответить
                      • элайнмент? ладно я тупой надо было читать контекст сначала
                        Ответить
                  • У меня в «x64» никаких «MOV EDI, EDI» нет, кстати. Только в 32-битных остались.
                    Ответить
          • > созданиеструктуры ленивым

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

              проблемы когда там исключение летит или когда аргумент конструктора в компайл тайме не посчитать
              Ответить
              • Появляется недетерминированность. Кто первый позвал того и тапки? При попытке получить с другим значением будет ошибка? Или там внутри мапа, чтобы каждому своё?
                Ответить
                • > Кто первый позвал того и тапки?
                  а разве это не есть "ленивый"?
                  Ответить
                  • Ну вот смотри. Один тред сказал Foo::GetInstance(42), второй тред сказал Foo::GetInstance(100500) и чо теперь делать?
                    Ответить
                    • ибо было сказано
                      >или когда аргумент конструктора в компайл тайме не посчитать
                      Ответить
              • Борманд вернулся
                Ответить
    • лучшее
      https://twitter.com/netovetz/status/1562957554321240065?cxt=HHwWgsClhazn3rAr AAAA
      Ответить
      • Всё, что происходит в твиттере, должно оставаться в твиттере.
        Ответить
        • Nein!

          https://nitter.fdn.fr/subzey/status/951429004095082496
          Ответить
          • Даже во время соловьиного помета можно было купить денег.

            > должно оставаться в твиттере
            Это про поносы, мисгендеринг и прочий новодел бес души.

            Вообще если подумать, то без президента Дональда Трампа никакого птичера, 44 лярдов ботов и прочего не было бы.
            Ответить
    • Так вот, ублюдок, я знаю, что ты это читаешь — пошёл ты нахуй. Ты никогда не сможешь сделать так, чтобы мой голос затих. Я буду являться тебе в ночных кошмарах.
      Ответить
    • Я раньше всё возмущался — неужели эти дураки не понимают, что так нельзя? Неужели не видят, сколько сил тратится впустую? Неужели не осознают, что мы колбасим килотонны одинакового по сути кода, за бешенные деньги, осознанно игнорируя бесконечное пространство для оптимизации своего труда, оптимизации разработки, оптимизации развития технологий а вместе с ними и мира людей?

      https://razrabs.ru/post/99d329da-a0a4-489b-85db-eeb41e6b02db
      Ответить
      • чет заржал с комментариев

        upd. ну кто блядь так форматирует?

        return speedA > speedB 
                ? a 
                : b;


        upd2.

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

        Ctrl + F maui: 0 результатов
        Ctrl + F xamarin: 0 результатов
        Ctrl + F avalonia: 0 результатов
        Ответить
        • Так есть же всякие замарины, реакт нативы и прочая шелупонь?
          Ответить
        • БЛЯДЬ!!!

          Я только ща понял: это же ебучий графоман с хабра, который по четыре статьи в неделю высирал? Филл девелопер или фил программер как там его?
          Ответить
          • Именно он. «Король разработки».
            И не просто по четыре статьи, а по четыре адски разжигающих статьи: https://habr.com/ru/users/fillpackart/.
            Ответить
            • ёптуж, я тоже до этого момента никак не ассоциировал
              Ответить
    • Не воспринимаю людей, которые не любят @fillpackart2

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

        https://twitter.com/fillpackart2/status/1564669399092666369
        Ответить
        • Мне кажется, они художники
          Ответить
        • Ну блин
          Стиральная машина это тот еще агрегат. Есть крутилка, на которой одна программа для одежды, другая для загрязнений; третья быстрая, четвертая легкая; пятая обычная, шестая повседневная; и между ними несколько отжимов. И это еще если прочитать инструкцию. Если не читать, то вообще https://pikabu.ru/story/kak_v_ney_stirat_1598525 .
          Ответить
          • Сейчас очень сложно не найти пдф мануала в интернете, при чем в худшем случае с какого-нибудь хорватского его поможет перевести гугл транслейт
            Ответить
            • Лепа наша домовино...
              Ответить
            • я как-то не нашёл мануала на нонейм бутусные наушники, с которыми попросили удалённо разобраться
              Ответить
          • Вчора на "обдуреному росіянині" показували, як окупанти крадуть з пограбованих будинків речі українців: Пральні машини, планшетки, ношені речі, також зубні щітки, а деже пакети з прокладками
            Ответить
    • ладно, вот вам смешное
      https://twitter.com/Mika_venerovna
      Ответить
    • заведите себе гуся https://twitter.com/Gabriele_Corno/status/1564561476911857664
      Ответить
    • https://twitter.com/Vorewig/status/1564514232124719106
      Ответить
    • И у всех одна претензия: «ты думаешь что ты лучше нас!!!»

      Бля ребят, если вас так сильно это беспокоит, ваша проблема не во мне нихуя

      Здоровому человеку должно быть похуй, что о нем думает напыщенный тупой айтишник
      Ответить
    • Но да, конечно, именно моё высокомерие причина всех их бед

      Так бы жили себе на ебучие страшные копейки и бед не знали бы

      Жалко сраный Фил всё испортил и сказал что это не жизнь нихуя
      Ответить
    • А то получается странно. На напыщенного айтишникам в твиттере они набрасываются как волки, а на своего хозяина, который с циничной ухмылочкой швыряет им поганые 20к рублей в месяц за ебейший труд они посмотреть лишний раз боятся
      Ответить
    • бой продолжается
      Ответить
    • https://stackoverflow.com/questions/73571853/can-you-tell-me-what-s-wrong
      Ответить
    • почему govnokod.ru, но не ru.govnokod?
      Ответить
      • Почему little-endian, но не big-endian.
        Ответить
        • не эквивалентно
          Ответить
          • Ну тогда, как обычно, потому что веб писали макаки.

            Так то твой вариант логичнее -- вся иерархия в правильном порядке получается. Джавка его юзает именно по этой причине.
            Ответить
            • https://www.quora.com/Why-are-top-level-domain-names-TLDs-at-the-end-of-a-domain-and-not-at-the-beginning

              Once you try to map a hierarchal structure into a linear name space, you have to choose an ordering scheme. The DNS chose to put the “root” to the right, kind of like “little endian” binary schemes used in some CPUs. The United Kingdom once had an academic network with a naming scheme that put the top level to the left. I.e.: “www.register.co.uk” would have been “co.register.www” (because it was a UK-only scheme, “uk.” wasn’t needed to the left.)

              UUNET had it’s own kind of naming scheme that was also a kind of routing scheme. There wasn’t a hierarchy at all. BITNET never grew large enough to need a non-flat name space.

              It’s arbitrary. Pick a scheme and stick to it.
              Ответить
            • почему веб? разве не DNS писали мокаки?
              Ответить
            • почему веб? разве не DNS писали мокаки?
              Ответить
      • Смотря где

        В usenet и fido было бы именно так
        Ответить
    • Пошли нахуй с моей ветки, это не оффтоп.
      Ответить
    • Если в проекте важна функциональная безопасность, и такой код нужно вылавливать как можно раньше, то нужно пользоваться статическим анализатором, для него этот случай простой, я думаю.
      Ответить
      • Ну как, устроился в Касперского?
        Ответить
        • А куда делся доктор веб? Антивирусная лабороатория Игоря Данилова
          У меня в детстве был

          Мой знакомый лет двадцать назад там работал

          Он вообше еще существует?

          ого
          я малость не успеваю за переменами
          https://www.cnews.ru/news/top/legendarnyj_rossijskij_antivirus_menyaet
          Ответить
    • https://twitter.com/POTUS/status/1565512354493857802
      Ответить

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