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

    +4

    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
    30. 30
    31. 31
    32. 32
    33. 33
    34. 34
    35. 35
    36. 36
    37. 37
    38. 38
    39. 39
    40. 40
    41. 41
    42. 42
    43. 43
    44. 44
    45. 45
    46. 46
    47. 47
    48. 48
    49. 49
    50. 50
    51. 51
    52. 52
    53. 53
    54. 54
    55. 55
    56. 56
    57. 57
    58. 58
    59. 59
    60. 60
    61. 61
    62. 62
    63. 63
    64. 64
    65. 65
    66. 66
    67. 67
    68. 68
    69. 69
    70. 70
    71. 71
    72. 72
    73. 73
    74. 74
    75. 75
    76. 76
    77. 77
    78. 78
    79. 79
    80. 80
    81. 81
    82. 82
    83. 83
    84. 84
    85. 85
    86. 86
    87. 87
    88. 88
    89. 89
    90. 90
    91. 91
    92. 92
    93. 93
    94. 94
    95. 95
    96. 96
    97. 97
    98. 98
    // https://govnokod.ru/26890#comment571155
    // bormand 2 часа назад #
    // Можно брейнфак запилить на операторах. Как раз вроде унарных хватает.
    // & * - ~ ! -- + ++ --
    
    #include <array>
    #include <vector>
    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <limits>
    
    struct Brainfuck {
    public:
        using IPType = uint16_t;
        constexpr static size_t MAX_MEMORY = std::numeric_limits<IPType>::max();
    
        std::array<uint8_t, MAX_MEMORY> memory{};
        std::vector<char> app{};
        IPType ip = 0;
        IPType cell = 0;
    
        IPType find_matching_tag(IPType cur_ip, char open, char close, int ip_direction)
        {
            size_t stack_size = 0;
            do  {
                if (app[cur_ip] == close) {
                    --stack_size;
                }
                if (app[cur_ip] == open) {
                    ++stack_size;
                }
                cur_ip += ip_direction;
            } while (stack_size > 0);
            return cur_ip - ip_direction;
        }
    
        IPType find_matching_close_tag(IPType cur_ip)
        {
            return find_matching_tag(cur_ip, '[', ']', 1);
        }
    
        IPType find_matching_open_tag(IPType cur_ip)
        {
            return find_matching_tag(cur_ip, ']', '[', -1);
        }
    
        void loop_open()
        {
            if (memory[cell] == 0) {
                ip = find_matching_close_tag(ip);
            } else {
                ++ip;
            }
        }
    
        void loop_close()
        {
            if (memory[cell] != 0) {
                ip = find_matching_open_tag(ip);
            } else {
                ++ip;
            }
        }
    
        void exec(char op)
        {
            switch (op) {
                case '>': ++cell; break;
                case '<': --cell; break;
                case '+': ++memory[cell]; break;
                case '-': --memory[cell]; break;
                case '.': std::putchar(memory[cell]); break;
                case ',': memory[cell] = static_cast<uint8_t>(std::getchar()); break;
                case '[': loop_open(); return;   // no ip advancing
                case ']': loop_close(); return;  // no ip advancing
            }
            ip++;
        }
    
        void run()
        {
            while (ip < app.size()) {
                exec(app[ip]);
            }
        }
    
    public:
        Brainfuck & operator++() { app.push_back('>'); return *this; }
        Brainfuck & operator--() { app.push_back('<'); return *this; }
        Brainfuck & operator+() { app.push_back('+'); return *this; }
        Brainfuck & operator-() { app.push_back('-'); return *this; }
        Brainfuck & operator*() { app.push_back('.'); return *this; }
        Brainfuck & operator&() { app.push_back(','); return *this; }
        Brainfuck & operator!() { app.push_back('['); return *this; }
        Brainfuck & operator~() { app.push_back(']'); return *this; }
        Brainfuck & operator>>(const Brainfuck &) { run(); return *this; }
    };

    https://wandbox.org/permlink/XJUKGyb4YbnBVwOI

    Бонус («99 bottles of beer»): https://pastebin.com/s4sBK9nX (взято с https://github.com/fabianishere/brainfuck/blob/master/examples/bottles-1.bf).

    Запостил: gost, 03 Сентября 2020

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

    • «Hello world!»:
      int main()
      {
          Brainfuck bf;
      
          * ++ * + ++ * - - - - - - - - * - - - - - - * + + + * ++ * + + + +
          + + + + + + + + + + + -- -- * + + ++ * + + + * * + + + + + + + * +
          ++ * + + ++ ~ - -- -- -- -- + ++ + + + ++ + + + + + + + + + + ++ +
          + + + + + + ++ ! + + + + + + + + + +
          bf >> bf;
          
          return EXIT_SUCCESS;
      }


      Перевод из классического «Брайнфака» в крестовый DSL:
      def translate(app: str) -> str:
          translation_table = str.maketrans({
              '>': '++ ',
              '<': '-- ',
              '+': '+ ',
              '-': '- ',
              '.': '* ',
              ',': '& ',
              '[': '! ',
              ']': '~ '
          })
          return app[::-1].translate(translation_table)
      Ответить
    • Зачем? Зачем? Это же просто шутка была...
      Ответить
      • Какая шутка )))
        Ответить
        • Жаль, что постфиксных операторов мало.
          Ответить
        • Всё таки брейнфак -- отличный язык. Его спецификация настолько проста, что ты написал его реализацию за два часа.
          Какой еще язык можно так быстро реализовать?

          а гост ебанутый малость, это уже очевидно
          Ответить
          • Подтверждаю.

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

                Закрывающая скобка цикла "пушит" правую часть в отдельное поле и начинает новую пустую цепочку. Открывающая скобка заворачивает эту цепочку в цикл и пристегивает к запушенному куску.

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

                S<Plus, Plus, Plus, Loop<Plus, Right, Minus, Left>, Out>

                S::operator() { dummy(args()...); } где dummy ничего не делает.

                Это вроде лучше инлайниться должно.
                Ответить
              • Бля, вот как теперь уснуть :(
                Ответить
            • Удобно эзотерические языки использовать для обучения компутер сайнс: ты ведь по сути и парсер реализовал, и виртуальную машину полноценную, и всё за 2 часа
              Ответить
            • PoC кодогеренации: https://ideone.com/UyFsgJ

              Осталось в операторы обмазать.
              Ответить
            • Осталось циклы доделать: https://ideone.com/Vaqfgv
              Ответить
            • https://ideone.com/BsrpOj

              Всё, заебало, будет без украшательств. Работает и ладно.

              Кстати в компайлтайме проверяет баланс циклов.
              Ответить
            • https://govnokod.ru/26911
              Ответить
          • Да, вот только ничего серьезного на нем не напишешь.
            Для рынка этот язык никчемный.
            Ответить
            • Как будто про "C++" написал.
              Ответить
              • Ну поищи вакансии "Программист Brainfuck", и вакансии "Программист C++". C++ всё еще нужен.
                Ответить
                • Ты ничего не понимаешь. Брейнфак - это будущее. Нейросети будут генерить программы на брейнфаке, а программисты на всяких "с++" и "джава" станут нинужны.
                  Ответить
    • показать все, что скрытоvanished
      Ответить
      • Х.з., привычка от биоса осталась?
        Ответить
        • показать все, что скрытоvanished
          Ответить
          • Ну тогда просто выебнуться хотел. В UEFI асма почти нет даже в реализации. Только стартовый код, который из 16 в 64 уходит и всякая мелочь однострочная.

            З.Ы. Ну в CSM ещё фрагменты есть для общения с 16-битной хуйнёй. Но тут явно не этот случай.
            Ответить
            • показать все, что скрытоvanished
              Ответить
              • Я на асме фреймворк с текстовыми окошками и кнопочками делал. Но сдуру начал всё писать на макросах и потратил все 64кб в сегменте кода. А более сложную модель памяти, сам понимаешь, с асма неприятно юзать.
                Ответить
                • типа турбовижен?
                  у меня почти все проги под реальный режим вообще были tiny, это я помню.

                  Но хуйню, которая грузится с загрузочной дискеты и выводит ":)" я тоже делал когда mbr изучал, а вот про uefi я знаю только в теории(
                  Ответить
                  • > только в теории

                    Да там ничего особо интересного. Гуиды да интерфейсы. Получаешь интерфейс по гуиду да зовёшь методы. Той магии, что была на биосе, там уже нет.
                    Ответить
                    • показать все, что скрытоvanished
                      Ответить
                      • Только 64, только хардкор.

                        32-битный уефи ты в природе хер найдёшь. Вроде больше не выпускают девайсов с ним.
                        Ответить
                        • показать все, что скрытоvanished
                          Ответить
                          • 64 без страниц не бывает. Но там 1:1 маппинг по спеке настроен, так что считай что нету.

                            В железо тебе там лезть не надо, там всё очень высокоуровневое. Даже к pci лазить будешь через интерфейс а не напрямую.

                            В прерывания тоже лезть не надо, там все на таймерах да ивентах. Да там кроме таймерного их и нет, лол.

                            Это по сути простенькая однозадачная ось.
                            Ответить
                            • Тоесть одна страница размером со всю память? Ну да, считай нету. А что там mmu делает -- мне пофиг.

                              >Даже к pci лазить будешь через интерфейс.
                              Там прямо сишные функции "энумирейт бас", "считать доступные адреса из спейса" и "настроить девайс"?

                              > на таймерах да ивентах.
                              Колбеки типа?
                              Ответить
                              • Да, прям сишные методы.

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

                                  Это может быть важно, чтобы игрушки писать. А для загрузочного экрана наверное пофиг. Тащемто биосный API для видео тоже тормозил.

                                  А для USB? SATA? Для этого говна тоже есть API, или там напрямую не нужно?
                                  Ответить
                                  • Да, есть интерфейсы для усб на уровне "послать контрол трансфер" или "дождаться интеррупт трансфер".

                                    Есть интерфейсы для дисков. Рид да врайт.

                                    Есть интерфейс для файлухи. Но изкоробки только фат да исо. Разделы и т.п. само подхватывает и публикует.

                                    В принципе там плуг энд плей даже.
                                    Ответить
                                    • контрол трансфер это который шлют в дефолтный эндпоинт чтобы сконфигурить девайс?

                                      Так прошивка сама всё конфигурит (это ведь и есть плуг энд плей), но ты можешь потом переконфигурить под себя?

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

                                        Да, прошивка сама все что может распознает и конфигурит. Лоу-левел интерфейсы это если ты свои дрова собрался писать.
                                        Ответить
                                        • >в точку входа
                                          типа
                                          void petuh(Govno* govno) {
                                           govno->DoAll();
                                          }

                                          ?

                                          Я просто не понял, а откуда я возьму printf?


                                          > Лоу-левел интерфейсы это если ты свои дрова собрался писать.
                                          Кстати, а что случилось с биосами устройств?

                                          Если я сделаю карточку, и хочу чтобы uefi мог с нее грузиться, я могу в карточке разместить какой-то код под efi, который сэмулирует из нее например диск или mass storage usb?
                                          Ответить
                                          • С сишной либой можешь сразу попрощаться.

                                            Аллокаторы, сосноль, всё через те таблички.
                                            Ответить
                                            • блядзь.

                                              то есть ответ на мой вопрос про рантайм -- хуй. Ну ок, тоже ничего.

                                              Остался вопрос про биосы устройств
                                              Ответить
                                              • Биосы pci устройств как и раньше в опшен ромах. Просто в виде PE образа теперь. В современных видюхах обычно и то и то лежит.

                                                А для всяких usb все и на дженерик дровах взлетает. Мышки, клавы, флешки и т.п.
                                                Ответить
                                                • ну usb просто: он может изобразить масс сторадж, и потечь. Вопрос был скорее про pci. Я понял, что там лежат PE.
                                                  Спасибо)
                                                  Ответить
                      • Кстати если будешь пробовать - компиль в студии. Ибо PE и виндовые соглашения. С gcc тоже можно, но там костыли да грабли.
                        Ответить
                        • показать все, что скрытоvanished
                          Ответить
                          • Ну да, проще всего на виртуалке. С флешкой пердолиться неудобно всё-таки.
                            Ответить
                            • А есть способ дебажить на реальном компе? ну там через ком порт, как раньше дебажили драйверы у винды и некоторых других ос
                              Ответить
                              • Жопа с этим, лучше на виртуалке.
                                Ответить
                                • и дебажиться выводом логов в консоль?
                                  или у виртуалок есть интерфейсы для дебага uefi?
                                  Ответить
                                  • На осдеве глянь статью.
                                    Ответить
                                    • ладно, спасибо) Правда, надо уже почитать вместо заебывания, а то я превращаюсь в сёму
                                      Ответить
              • А первым моим кодом на асме был тот самый эмулятор 8080. Там только само ядро на асме, остальное пасцаль.
                Ответить
    • Ебать поехавший.
      Ответить
    • Гомоиконка.
      Ответить
    • Уважаю.
      Ответить
    • В чём прикол std::array вместо массива? Для анскильных лалок что-то?
      Ответить
      • У него всякие няшные методы есть, как у других контейнеров. И его можно вернуть.
        Ответить
        • показать все, что скрытоvanished
          Ответить
          • Недавно видел как петух забыл инициализировать массив {}.
            Ответить
            • показать все, что скрытоvanished
              Ответить
              • > будут данные

                Нет. Чтение неинициализированных данных - UB. Вплоть до полного разрушения логики и true = false в других местах программы.

                Не надо так делать.
                Ответить
                • показать все, что скрытоvanished
                  Ответить
                • > Чтение неинициализированных данных - UB.
                  кроме чара и байта вроде, это довольно логично

                  вероятно, и массив байтов можно читнуть
                  Ответить
                  • Это кто такое сказал?
                    Ответить
                    • Read from an indeterminate byte

                      if an indeterminate value of type unsigned char or std::byte (since C++17) is assigned to another variable of type (possibly cv-qualified) unsigned char or std::byte (since C++17)(the value of the variable becomes indeterminate, but the behavior is not undefined);

                      https://en.cppreference.com/w/cpp/language/default_initialization

                      Если я верно понимаю, то написано так:

                      Да, ты можешь считать любое значение. Но компьютер не сгорит. А если ты считаешь его из булена, например, то у тебя может нарушиться true != false или еще что-то такое
                      Ответить
                      • Там дальше реальный пример приведён:
                        int f(bool b)
                        {
                            int x;               // OK: the value of x is indeterminate
                            int y = x;           // undefined behavior
                            unsigned char c;     // OK: the value of c is indeterminate
                            unsigned char d = c; // OK: the value of d is indeterminate
                            int e = d;           // undefined behavior
                            return b ? d : 0;    // undefined behavior if b is true
                        }

                        Ты можешь присвоить indeterminate value из одного байта только другому байту. Если ты потом попытаешься получить доступ к этому indeterminate value (например, попробуешь его вывести на экран) — всё равно получишь UB.
                        Ответить
                        • А зачем они разрешили читать байты?
                          Ответить
                          • Хуй знает, для байтоёбиков каких-нибудь, наверное. Чтобы можно было спокойно ворочать байтики туда-сюда или что-то в этом роде.
                            Ответить
                            • Кстати, а обращение к MMIO портам - тоже UB? С точки зрения крестов я же их никак не инициализировал.

                              Хотя, с другой стороны, они обычно volatile поэтому конпелятор не выёбывается.
                              Ответить
                        • КАКОЙ БАГОР )))
                          Ответить
                        • да, совершенно верно.

                          Ну ведь это же логично: один байт всегда валиден, какое бы говно ты туда ни пихнул.

                          А int совсем нет.

                          Допустим, на какой-то системе старший бит инта обязан быть единицией. Или обязан быть чексуммой. Если это не так, то процессор взрывается.

                          А ты сунул туда говно, и всё сломалось.

                          > Если ты потом попытаешься получить доступ
                          хм.
                          А вот тут я не уверен: является ли UB вывод этого байта в cout?
                          Ответить
                          • Судя по int e = d - является. Любая арифметика же сначала в инт переводит.

                            Хотя... если он прям сразу в буфер с байтами пишется...
                            Ответить
                            • я именно про буфер

                              char a;
                              char b[1];
                              b[0] = a;

                              так можно?



                              C++ стоит учить именно ради того, чтобы вести такие беседы,лол
                              Ответить
                              • Ну судя по unsigned char d = c; - да.

                                Хотя, емнип, примеры в стандарте не являются нормативными и на них нельзя строить пруфы.
                                Ответить
                                • в общем ощущение такое, что я могу взять любой байт в памяти, и сказать: "вот байт" и это будет правда

                                  А взять любые 4 байта и сказать "вот инт" я не могу: это может быть не правдой.

                                  Так я трактую cppref, но надо читат стандарт
                                  Ответить
                              • Можно.
                                If an indeterminate value is produced by an evaluation, the behavior is undefined except in the following
                                cases:
                                    (2.1) — If an indeterminate value of unsigned ordinary character type (6.8.1) or std::byte type (17.2.1) is
                                    produced by the evaluation of:
                                        (2.1.1) — the second or third operand of a conditional expression (7.6.16),
                                        (2.1.2) — the right operand of a comma expression (7.6.20),
                                        (2.1.3) — the operand of a cast or conversion (7.3.8, 7.6.1.3, 7.6.1.8, 7.6.3) to an unsigned ordinary character
                                        type or std::byte type (17.2.1), or
                                        (2.1.4) — a discarded-value expression (7.2.3),
                                    then the result of the operation is an indeterminate value.
                                    (2.2) — If an indeterminate value of unsigned ordinary character type or std::byte type is produced by the
                                    evaluation of the right operand of a simple assignment operator (7.6.19) whose first operand is an lvalue
                                    of unsigned ordinary character type or std::byte type, an indeterminate value replaces the value of
                                    the object referred to by the left operand.
                                    (2.3) — If an indeterminate value of unsigned ordinary character type is produced by the evaluation of the
                                    initialization expression when initializing an object of unsigned ordinary character type, that object is
                                    initialized to an indeterminate value.
                                    (2.4) — If an indeterminate value of unsigned ordinary character type or std::byte type is produced by the
                                    evaluation of the initialization expression when initializing an object of std::byte type, that object is
                                    initialized to an indeterminate value.

                                § 6.7.4/2
                                Ответить
                          • З.Ы. На самом деле, я вот никогда не заморачивался с этим тонкостями и считал что для любого типа там UB. Для практических применений это вполне норм.
                            Ответить
                            • а вдруг мне вот совсем реально насрать что там в байте?
                              пускай я хочу чтобы там был любой мусор в зависимости от желания компилятора

                              зачем мне тратить инструкцию на заплнение инта чем-то?
                              Ответить
                              • А, так вот зачем это... чтобы memcpy на структурах с паддингом не UB'ом был!
                                Ответить
                                • а memcpy побайтику читает же?
                                  Ответить
                                  • Вообще говоря нет, там чуть ли не SSE. Но эти чуваки спят с разрабами конпеляторов, так что им можно.

                                    З.Ы. Но по стандарту там и на входе и на выходе конечно же байты.
                                    Ответить
                          • > А вот тут я не уверен: является ли UB вывод этого байта в cout?
                            Все выводящие байт функции (put, putchar, fputc, etc.) принимают int, поэтому вывод через них — является. Аргументы всех функций форматированного вывода (fprintf, printf, etc.) сначала integer promotятся, поэтому через них тоже вывести не получится. А поведение basic_ostream::operator<<(..., unsigned char) по Стандарту я сейчас подробно изучаю.
                            Ответить
                            • и точно: int putchar(int c) даже, значит нельзя

                              интресно про стрим
                              Ответить
        • Это я понял. Здесь то зачем?
          Ответить
          • Примерно затем же, зачем в современных крестах везде используют std::make_(unique|shared) вместо явного вызова new. Чтобы в коде было поменьше говна.
            Ответить
    • > std::vector<char> app{};

      Скобки нахуя?
      Ответить
      • Явно инициализировать любые объекты — признак хорошего тона.
        Ответить
        • Разве нетривиальный (не под) объект сам не должен инициализироваться подходящим дефалтктором?

          Так понимаю, что до 11 у тебя вообще выбора не было: фигурные скобочки писать было нельзя, а круглые (благодаря Most vexing parse) -- тоже.
          Ответить
          • Сам инициализируется, да. А если это какой-то хитрый тайпдеф а-ля «using PetuhNonTrivialMamoyKlyanus = int;» — получишь багор. Или потом кто-нибудь заменит нетривиальный тип на тривиальный, а написать инициализатор забудет. Гораздо проще и надёжнее явно инициализировать дефолтными конструкторами все объекты. Явное лучше неявного, все дела.
            Ответить
    • Почему у тебя открывающая скобка у класса на одной строке, а у метода на другой?
      Ответить
      • Это кодстайл K&R (ну, кроме мест, где пришлось строки экономить), расширенный Страуструпом.
        Ответить
    • > std::putchar

      Так вот зачем лалки придумали «cstdio» вместо «stdio.h».
      Ответить
      • Ага. Причём там есть один багор: «cstdio» всегда помещает своё говно в std::, но не гарантирует, что это говно будет в глобальном пространстве. «stdio.h» же всегда помещает говно в глобалки, а в std:: — не гарантированно.
        Ответить
    • Давайте обосрём этот код по максимуму.
      Ответить
      • Можно вылететь за границы memory и насрать туда.

        Ибо массив на 65535 элементов вместо 65536.
        Ответить
        • Ебать, вот это багорище! Какой анскилл (((
          Ответить
          • Да это ладно, там походу ещё с app аналогичная проблема. Если юзер вобьёт что-то в духе "[".
            Ответить
            • > Если юзер вобьёт что-то в духе "["
              Да это-то похуй, несбалансированные циклы — это UB. А вот память задумывалась полноценно циклической.
              Ответить
              • > несбалансированные циклы - это UB

                Слова не мальчика, но крестостандартизатора.
                Ответить
                • > несбалансированные циклы - это UB
                  Что-то гугл мне не помог по этому понятию, где о них почитать?
                  У Кнута?
                  Ответить
                  • Эм, в документации к твоему компилятору брейнфака.
                    Ответить
                  • я конечно не эксперт в с++ или brainfuck но мне кажется что это значит что за [ должно иди ]
                    Ответить
    • На строках экономил, чтобы в говнокод влезть?
      Ответить
    • показать все, что скрытоvanished
      Ответить
    • > struct Brainfuck {
      > public:

      Структура и так public. И по смыслу здесь не структура, а класс.
      Ответить
    • > ip

      Просто охуенное название переменной.
      Ответить
      • > using IPType = uint16_t;

        Первое о чём подумал, нахуя здесь тип айпишника, и при чем он в brainfuck.
        Ответить
      • Ну, во всяческих ВМах и интерпретаторах это стандартное обозначение, тут ничего не поделаешь.
        Ответить
    • Ну до кодстайла я доёбываться не буду, я хз какой он у вас. Но выглядит как хуйня.
      Ответить
    • > std::vector<char>
      std::string

      Программа по смыслу - это строка.
      Ответить
      • А я вот не помню, есть ли в std::string push_back() с амортизированным O(1).
        Ну и по-хорошему там вообще должен быть std::deque<char> и push_front() в операторах.
        Ответить
    • Продолжаем ревьювить доёбываться. Почему одинаковый тип для ip и cell? Сёмантически это совершенно независимые вещи. И ip может быть больше 65к, в отличие от cell.

      Или код длиннее 65к - тоже UB?
      Ответить
      • Пусть идёт исправлять текущие замечания. После будем обсирать дальше.
        Ответить
        • Он уже переписал на функциональную метушню с бесконечной лентой вместо массивов.
          Ответить
      • > Сёмантически это совершенно независимые вещи. И ip может быть больше 65к, в отличие от cell.
        Подтверждаю, инженерный отдел напутал cell и app.

        > Или код длиннее 65к - тоже UB?
        А и то правда!
        Ответить

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