Кресты / Говнокод #26910 Ссылка на оригинал

0

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  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 gost, (Updated )

Комментарии (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)
    Ответить
      • Всё таки брейнфак -- отличный язык. Его спецификация настолько проста, что ты написал его реализацию за два часа.
        Какой еще язык можно так быстро реализовать?

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

          > Его спецификация настолько проста, что ты написал его реализацию за два часа.
          И бо́льшая часть времени заняла реализация циклов (только под самый конец осознал, что [ может сразу же переместиться к ], поэтому просто последовательно по одному символу проходить не получится).
          Ответить
        • Да, вот только ничего серьезного на нем не напишешь.
          Для рынка этот язык никчемный.
          Ответить
            • Ну поищи вакансии "Программист Brainfuck", и вакансии "Программист C++". C++ всё еще нужен.
              Ответить
              • Ты ничего не понимаешь. Брейнфак - это будущее. Нейросети будут генерить программы на брейнфаке, а программисты на всяких "с++" и "джава" станут нинужны.
                Ответить
      • Чел в 2020 MSc Student Computer Science at Delft University of Technology, конечно у него привычка от биоса. Или от прогрммирования на асме под спектрум в 1986-м году, я уверен
        Ответить
        • Ну тогда просто выебнуться хотел. В UEFI асма почти нет даже в реализации. Только стартовый код, который из 16 в 64 уходит и всякая мелочь однострочная.

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

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

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

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

                        Может и стоит в это прыгнуть, но современное железо дохуя сложное.
                        Классический PC был как-то понятный: вот контроллер прерываний, вот контроллер клавиаутуры (и похуй, что они в чипсет спрятаны уже давно), а теперь понавертели всего.. В ACPI например я хуй знает с какой попытки врублися, и то наверняка не всё про него знаю
                        Ответить
                        • 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 тоже можно, но там костыли да грабли.
                      Ответить
                      • лол, MS протолкнуло PE в прошивку? Сраный wintel)

                        А на чем дебажить? На виртуалках?
                        Ответить
                        • Ну да, проще всего на виртуалке. С флешкой пердолиться неудобно всё-таки.
                          Ответить
                          • А есть способ дебажить на реальном компе? ну там через ком порт, как раньше дебажили драйверы у винды и некоторых других ос
                            Ответить
                              • и дебажиться выводом логов в консоль?
                                или у виртуалок есть интерфейсы для дебага uefi?
                                Ответить
            • А первым моим кодом на асме был тот самый эмулятор 8080. Там только само ядро на асме, остальное пасцаль.
              Ответить
              • нихуясе

                мои первым кодом было мигание лампочками на клаве.. там был io порт вроде, и туда надо было писать
                Ответить
                  • можно, у борланда был api, и даже в регистры писнуть можно было без асма, и даже обработчик прервания сделать вообще без асма, но я именно асм учил
                    Ответить
                    • В «Турбо Паскале» были псевдомассивы Mem и Port, запись в которые и чтение из которых транслировались в соответствующие инструкции (хотя массив Mem не нужен, ведь можно просто разыменовать указатель), а в сишке — функции inp и outp (да, названия в стиле «Позикса», как будто за каждую букву нужно кому-то платить).
                      Ответить
                      • Ты тоже страдаешь заблуждением, что по команде -o можно в дебагексее внести изменения в биосЪ?..
                        Ответить
                      • >хотя массив Mem не нужен, ведь можно просто разыменовать указател
                        в паскале тоже?
                        Ответить
                          • а как?
                            я чото не помн

                            вот в сишечке помню даже макрос(?) был для сегмент-смещение
                            Ответить
                              • дададада, была, вспомнил, спасибо!
                                Ответить
                                • Хех, поставить что ли паскаль, покопаться в своих древних копролитах.
                                  Ответить
                                  • а ты их хранишь?
                                    Я всё проебал уже.

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

                                      А фиг знает, возможно в старых бекапах есть. Я давно туда не заглядывал. Может быть уже и проебал.
                                      Ответить
                            • Да, в сишечке был макрос с нечитаемым названием MK_FP или типа того («make far pointer»?), но ведь макрос должен во что-то раскрываться. А раскрывался он в оператор :> (да, из двух символов), который «Borland», «Microsoft», «Watcom» и другие производители компиляторов специально добавили в язык для сегментной модели. НЕ ПО СТАНДАРТУ!!!
                              Ответить
                              • да там и слово "far" не по стандарту
                                А как еще быть?

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

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

                                    __alignof__ например
                                    Ответить
  • В чём прикол std::array вместо массива? Для анскильных лалок что-то?
    Ответить
    • У него всякие няшные методы есть, как у других контейнеров. И его можно вернуть.
      Ответить
      • Кстати, кривизна array в няшной это ошибка на миллиард долларов

        Сколько питухов на это наступило -- это просто пиздец
        Ответить
        • Недавно видел как петух забыл инициализировать массив {}.
          Ответить
          • ну так ведь там реально будут данные
            просто не понятно какие именно
            Ответить
            • > будут данные

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

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

                А такое в реальной жизни может быть?

                >Не надо так делать.
                никогда так не делал, конечно
                Ответить
                • Если там bool, enum или float - запросто.

                  Ну с int или char, скорее всего, ничего особо страшного не случится.
                  Ответить
                  • понял тебя.
                    Если енум может быть 1,2,3 а там 4, то буй знает, как он будет работать дальше
                    Ответить
                    • Ну да. А с булом я своими глазами видел когда обе переменных были true, но их && был false. И эта хуйня за счёт оптимизаций расползается довольно далеко.

                      А флоат просто крашнуть процесс может. Хотя это обычно отключено.
                      Ответить
                      • условно говоря, на какой-то платформе bool в одном месте проверяется как
                        a == b
                        а в другом на false проверяется как a == 0

                        если у тебя в a == 1, а в b 2, то они оба true, но не равны

                        типа такого?
                        >А флоат просто крашнуть процесс может.
                        FPU охуеет от мусора?
                        Ответить
                        • Да, примерно так. Плюс && и || оптимизируются до побитовых & и | чтобы лишние инструкции не писать. Поэтому они для таких чисел возвращают полную хуйню.
                          Ответить
                          • всё, я понял, какое может быть гавнино)

                            хорошо, что никогда так не делал

                            зы: прикольно, что клюнуть тебя это может через 4 часа в другом месте программы на конкретном CPU, например

                            охуеть)
                            Ответить
                          • Можно ли memset-ом заполнить массив булеанов true-ми?
                            Ответить
                            • думаю можно, если кастить int в bool явно, не?

                              кстати, в с89 нет никаких булен
                              именно потому я за борлад си 3

                              но float всё равно есть
                              Ответить
                            • Нет, если ты не знаешь физическое представление true на конкретном конпеляторе.

                              Там вроде только при нормальном касте в инт гарантируется единичка. А в самом буле запросто может лежать FF.
                              Ответить
                              • Можно в рантайме скопировать true в байт, и потом этим байтом заполнить?
                                Ответить
                                • Да. Насколько я помню, стандарт разрешает копировать числа побайтово через char*.
                                  Ответить
                                  • вот так же можно же
                                    bool bools[20];
                                    	memset(bools, (bool)1, sizeof(bools));

                                    или нет?
                                    Ответить
                                      • а почему?

                                        потому что (bool)1 не обязан был байтом?
                                        Ответить
                                        • В memset нужно закинуть int, который соответствует байтовому представлению була. Твой вариант никак это не делает.
                                          Ответить
                                    • Нет. sizeof(bool) is not required to be 1.

                                      Ну и ты забиваешь его единичками а не true.
                                      Ответить
                                      • Приведи реальный пример sizeof(bool) != 1
                                        Ответить
                                      • всё, понял

                                        если bool больше char, то я отсосу

                                        >Ну и ты забиваешь его единичками а не true.
                                        так разве (bool) не должен превратить единичку в true?

                                        ну ок, а если бы там true было?

                                        отсос правда все равно будет, если бул больше байта
                                        Ответить
                                          • а в чем?
                                            bool bools[20];
                                            	if (sizeof(char) == sizeof(bool)) 
                                            	{
                                            		memset(bools, true, sizeof(bools));
                                            	}

                                            вот так тоже нельзя?
                                            Ответить
                                            • (int)true - это всегда 1.
                                              Но true может быть и 0xFF
                                              Ответить
                                              • и что?
                                                каст единицы в бул разве не должен представить его в настоящее представление бул? Это же не реинтерпретер по сути, а статик, не?

                                                всё, понял: (int)true == 1, даже если там не 1
                                                Ответить
                                                • > каст единицы в бул

                                                  Каст була в инт возвращает 0 или 1. Независимо от внутренного представления була.

                                                  Каст инта в бул возвращает false для 0 и true для остального. Независимо от внутренного представления була.
                                                  Ответить
                                                  • говно какое вам мемсет, понял
                                                    Ответить
                                                • У memset второй аргумент - это int. Ты туда передаёшь true, поэтому он статик кастится в 1. Вне зависимости от платформы.
                                                  Ответить
                                                  • да, я понял, спасибо

                                                    memset нифига не "байтами" заполняет, а интами
                                                    ужасно
                                                    Ответить
                                                    • > интами

                                                      Ну он чарами заполняет. Просто исторически сложилось, что он в интерфейсе инт принимает.
                                                      Ответить
                                                    • Почему? Байтами. memset(g, 0xFF, sizeof g) заполнит всё 0xFFFFFFFF
                                                      (int32 g[100500])
                                                      Ответить
                                                      • я имею ввиду, что он не берет реальный байт из памяти, как сделал бы например memcpy если бы я передал бы ему указатель на мой массив , а получает int, и происходит каст в инт.

                                                        Если бы там был char, то был бы каст в чар, а толку
                                                        Ответить
                                            • > вот так тоже нельзя?

                                              Нельзя. Ты заполняешь единичками а не true ибо memset принимает int, а (int)true это 1. Он не шаблон.

                                              std::fill(std::begin(bools), std::end(bools), true) и не еби мозг.
                                              Ответить
                                              • типа memset превратит мой bool в единицу, даже если bool на платформе не единица, пушо там int?

                                                ох ебать
                                                Ответить
                                      • > (bool)1 - это true

                                        Но memset принимает int. А (int)(bool)1 это 1. А true это не обязательно 1. И вообще бул может быть больше байта (хотя я такого идиотизма нигде не видел).
                                        Ответить
                                      • не ебать я могу вероятно
                                        bool bools[20] = {true};

                                        так
                                        Ответить
                                        • Нет. Ты только первый бул заполнил true. Остальные 19 будут false.
                                          Ответить
                                          • ну я привел пример, разумеется я бы написал явно true для всех членов
                                            Ответить
                                            • А прикинь, если для одного забудешь? Кресты ведь тебе ничего не скажут.

                                              Ну, по крайней мере, там будет false а не UB.
                                              Ответить
                                              • сосну, да

                                                ладно, так то можно?
                                                bool bools[4] = {true, false, false, true};
                                                	bool bools2[4];
                                                	_memccpy(bools2, bools, 4, sizeof(bools));

                                                ?
                                                Ответить
                                                • Да, так можно. Только что за странный мемсру у тебя такой. С подчёркиванием.

                                                  З.Ы. А, это MS так позиксовые функции уродует.
                                                  Ответить
                                                  • забавно, что анскилябра типа меня может годами сидеть на платформе где true это 1, и делать memset без единого ворнинга и всё будет работать, и я даже не буду знать, что пишу хуйню

                                                    >уродует
                                                    да, у них есть CopyMemory свой
                                                    Ответить
                                                • Мне не нравится этот приём, кстати. Вот будут у тебя массивы разной длины. И эта функция "безопасно" заполнит не до конца. И в конце массива притаится UB.

                                                  Имхо, лучше уж явно проверить в начале, возможно даже static_assert'ом. А потом и обычный memcpy сойдёт.
                                                  Ответить
                                                  • можно видимо
                                                    CopyMemory(bools2, bools, sizeof(bools));
                                                    или как-то так
                                                    Ответить
                                                    • З.Ы. Именно поэтому я за std::array. Его можно просто присвоить, лол.
                                                      Ответить
                                                      • что будет, если я
                                                        std::array<int, 5> myArray = {1, 2, 3, 4, 5};
                                                        А потом присвою ему массив на 200 интов?

                                                        я не пишу на крестах просто, я и на няшной раз в год пишу, и стараюсь всё делать явно, чтобы не словить багра
                                                        Ответить
                                                        • Ошибка компиляции: нет оператора присваивания для std::array<int, 200> и std::array<int, 5>

                                                          Только одного типа и размера можно присваивать друг другу.
                                                          Ответить
                                                          • тогда заебись, конечно.
                                                            а конструктора тоже нет? нельзя myArray(hugeArray)?
                                                            Ответить
                                                            • Не, даже в инициализаторе сильно много не засунешь. Впрочем как и в обычный сишный массив.
                                                              Ответить
                                                              • ты просто сказал "просто скопировать", вот я и спросил

                                                                в моем жабоёбном мире анскилябров все говно работает через указатели, так что можно присваивать, размер там чисто динамическое понятие
                                                                Ответить
                                                              • а в std бывает питушня, которая сама автоматически создает что-то в куче? Или там всегда программист решает?
                                                                Ответить
                                                                • "Сама" это как?

                                                                  Ну вектора и мапы всякие с кучей работают.
                                                                  Ответить
                                                                  • сама -- это значит без явного указания

                                                                    vector растет динамически, и делает это в куче?
                                                                    Ответить
                                                                    • Ага, растёт "удвоением" по мере вставки элементов.

                                                                      Ну как ваш ArrayList.
                                                                      Ответить
                                                                      • Понятно. Похож на наш ArrayList тогда.

                                                                        А бывают такие платформы, где нету кучи, а только стек?
                                                                        Если да, то там C++ не работает получается?
                                                                        В няшной по идее в них можно было бы убрать malloc, и всё
                                                                        Ответить
                                                                        • Ну кресты вполне юзабельны без кучи.

                                                                          И даже вообще без стандартной либы. Но это уже просто няшная с RAII и шаблонами.
                                                                          Ответить
                                                                          • но вектор там не заведетcя, да?
                                                                            Ответить
                                                                            • Но вектор там не заведётся, да.

                                                                              И исключения тоже, по крайней мере в gcc. Там чуть-чуть аллокатор зовётся при старте. Возможно и потом при каких-то условиях (слишком жирное исключение или второе подряд?) Я сильно не изучал.

                                                                              Придётся на них тоже забить если кучи нету.
                                                                              Ответить
                                                  • ну понятно что в реальном коде я бы вынес 4 в константу, и не копипастил бы ее везде
                                                    Ответить
                                • Только я вот не уверен, что sizeof(bool) == 1...

                                  sizeof(bool) is not required to be 1
                                  Ответить
                              • так а что мне мешает явно кастануть в bool?
                                или сделать массив bool, взять его адрес, и местенуть?
                                Ответить
              • > Чтение неинициализированных данных - 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'ом был!
                              Ответить
                                • Вообще говоря нет, там чуть ли не 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. Чтобы в коде было поменьше говна.
          Ответить
    • Явно инициализировать любые объекты — признак хорошего тона.
      Ответить
      • Разве нетривиальный (не под) объект сам не должен инициализироваться подходящим дефалтктором?

        Так понимаю, что до 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 но мне кажется что это значит что за [ должно иди ]
                  Ответить
  • На строках экономил, чтобы в говнокод влезть?
    Ответить
  • Я часто думаю: почему С++ программисты обсирают свой язык, а например PHP программисты -- нет?

    Типичные крестовики это Борманд и Гост, постоянно пишущие, что С++ -- монструозное говно.
    А типичный PHPшник это Конардо.

    Я пришел к выводу, что программисты на С++ более интеллектуально развиты, и как следствие более склонны к рефлексии. Подобный паттрен мы наблюдает не только у программистов: умные люди часто путаются и рвутся, думая "а не хуйню ли я сделал?", в то время как дебилы всегда жизнерадостны, и полностью уверены в своей правоте.

    Думаю, дело в этом.
    Да?
    Ответить
        • потому что последний стандарт с++ - с++20, а у php - только php7
          Получается что php получилось довести до совершенства только за 7 версий,
          а с++ и за 20 не смогли
          Ответить
            • оказывается что сначала был с++98 а потом с++03
              наверное сишники опять проебались и случилось переполнение численного типа
              Ответить
              • С виндой тоже такая херня есть

                По какой-то причине win10 новее win95, хотя очевидно же, что 10 меньше!

                Ебланы
                Ответить
    • А если я уверен в том, что всегда делаю хуйню?
      Ответить
  • > struct Brainfuck {
    > public:

    Структура и так public. И по смыслу здесь не структура, а класс.
    Ответить
    • угу, структура в крестах вроде и есть класс с публиками
      Ответить
    • Ну и приветные кишки у него почему-то public.
      Ответить
    • Опечатка, там private: должен быть, конечно. А структура — потому что по изначальной задумке там никаких кишков не было, а потом уже на class поменять забыл.
      Ответить
  • > ip

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

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

    Программа по смыслу - это строка.
    Ответить
    • А я вот не помню, есть ли в std::string push_back() с амортизированным O(1).
      Ну и по-хорошему там вообще должен быть std::deque<char> и push_front() в операторах.
      Ответить
      • Unspecified. Generally O(1) but can be up to O(n).

        Ну видимо потому что вектор позже появился. А хреновых строк уже понаписали.
        Ответить
        • Ебать. Как у строк можно сделать не омортизированный О(1) push_back? Научите?
          Ответить
          • Ну как, как. Наивная реализация без capacity с реаллоком на каждый чих.
            Ответить
            • Каким долбоебом нужно быть, чтобы сделать такое в стандартной либе?
              Ответить
              • Наивным чуваком из восьмидесятых?

                В первых крестах даже контейнеров и алгоритмов то не было, стринг да иострим.
                Ответить
                • А почему до сих пор не исправили?
                  Ответить
                  • Исправили, generally O(1) же. Но древние реализации не выбрасывать же на помойку, вот стандарт и не запрещает писать хуйню.

                    А вот для вектора он явно требует амортизированное О(1).
                    Ответить
                    • Ну то есть в gcc, clang и msvc всё нормально? Хули тогда гост пиздит, что не уверен?
                      Ответить
                      • Я вот про старый сибилдер ещё не уверен... Но проверить нечем.
                        Ответить
                    • Почему не начать требовать начиная с какого-то стандарта?
                      Ответить
                      • Потому что разрабы конпеляторов начинают плакать: "у нас же ABI, у нас куча софта и либ на старой реализации сидит, не пересобирать же всё".
                        Ответить
                        • А другие как переделывают и не ноют? Ну и пусть тогда сидят на старых стандартах, и ничего не делают. В чём проблема? И вообще, в чём проблема переписать реаллок на нормальный? Или они не могут добавить size_t capacity не ломая ABI?
                          Ответить
                          • Ну да, для наивных реализаций это новое поле.

                            И комитет всегда реально ссыт кому-то что-то сломать.

                            Там до смешного доходит, когда новые классы добавляют вместо того, чтобы пофиксить старые. И теперь у тебя есть выбор между scoped_lock, unique_lock и lock_guard.
                            Ответить
                            • Я предумал.
                              Можно хранить capacity в первых байтах строки, а саму строку со сдвигом.
                              Ответить
                              • Ну дык ты один хер сломал ABI, как не крути. Старая либа охуеет от новой строки (capacity вместо символов). Новая либа охуеет от старой (символы вместо capacity).
                                Ответить
                                • Почему она охуеет, если логика обработки данных вся в библиотеке, а не в хедерах?

                                  UPD: всё, понял
                                  Если я передам в какую-то другую либу новую строку, то она охуеет.
                                  Ответить
                      • К слову, в с++17 они таки решились затащить кучу пунктов, которые ломают совместимость. Даже auto_ptr выпилили.

                        Надо глянуть, может там добавили пункт про О(1) у строки.
                        Ответить
            • Ну в общем-то stringstream есть, можно по-жабьему строчки клеить.
              Ответить
  • Продолжаем ревьювить доёбываться. Почему одинаковый тип для ip и cell? Сёмантически это совершенно независимые вещи. И ip может быть больше 65к, в отличие от cell.

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

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

Добавить комментарий для guest Отменить ответ

Где здесь C++, guest?!

    А не использовать ли нам bbcode?


    8