1. Си / Говнокод #29101

    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
    typedef struct ll_node
    {
      struct ll_node *prev;
      struct ll_node *next;
      int val;
    } ll_node;
    
    ll_node a;
    ll_node b;
    ll_node c = {&a, &b,3};
    
    // не работает
    a.next = &b;
    a.prev = &c;
    
    b.next = &c;
    b.prev = &a;
    
    /*
    c.next = &a;
    c.prev = &b;
    */
    
    // зато так работает:
    ll_node arr[3] = {
      {&arr[2], &arr[1],1},
      {&arr[0], &arr[2],2},
      {&arr[1], &arr[0],3}
    };

    Кольцевой двусвязный список.

    Запостил: j123123, 10 Марта 2025

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

    • Держать все элементы такого списка в одном массиве только чтоб ссылаться друг на друга, и свободно ссылаться можно было только внутри этого массива... это говно какое-то
      Ответить
      • Self-reference structure это вообще известная боль. Я вот сделал структуру на стеке, а потом вернул ее из функции, и чото она сломалась, угадайте почему.

        Существуют разные решения:
        1. Крестоблядское. Там указатели правят в конструкторах которые вызываются при передвижении структуры
        2. Растовое. Запретить такое нахуй, и всё. Хочешь ссылаться с кошечки на собачку? Положи их в массив, и ссылайся на первый элемент или на второй.
        3. GCблядское: положи всё в кучу, и не парься.

        Впринципе, в няшной тоже можно сделать вариант 3, наверное.
        Ответить
        • Если структуру, выделенную на стеке, возвращать по значению, она может сломаться, хотя может и не сломаться. Если например структура в себе хранит указатели на себя же, она 100% сломается т.к. при возврате там адреса будут уже другие. Хотя тут можно изъебнуться по-хитрому и распидорить стекфрейм, ну чтоб адрес возвращаемой структуры остался тем же для той функции, в которой вернулось управление. Т.е. эта структура теперь формально будет локальной переменной уже той функции, которая уровнем ниже. Но такого говна скорее всего нигде не реализовано, и для этого надо особый ABI
          Ответить
          • Сама структура же не двигается относительно дна памяти, только относительно укокозателя стека.
            Ответить
            • Вот да, для пирфоманса данные в стеке не двигают, двигают только указатель на вершину стека (у аппаратного стека x86 эта «вершина» находится внизу, стек растёт вниз, чтобы всё его содержимое было по положительному смещению от SP).

              Если бы двигали сами данные, затраты энергии были бы пиздец какими.

              Данные двигают в плавпитухе, но там и объёмы смешные: 8 регистров по 80 байт.
              Ответить
            • Это зависит.


              Скорее всего она будет создана на вызываемой стороне, но в целом не обязана
              Ответить
    • Жалко, что в ЯП нету относительных указателей. Можно, конечно, вручную сделать относительные указатели пердольным способом.

      Указатели создают барьеры для deep copy и для reallocate.
      Ответить
      • относительный указатель это и есть смещение в массиве:)

        Погугли про боль растишек про self-reference structure, это очень смешно: там нужен Pin + unsafe.
        Ответить
        • Точно. Если в качестве указателя используется индекс массива, то его спокойно можно копировать или перемещать.
          Ответить
    • А что не работает-то? У меня компилится
      Ответить
      • что у тебя компилится? тут даже main нету))

        попробуй положить это в функцию, и потом передать куда-то 'a'
        Ответить
        • Та я её в майн и положил.

          Если вы адреса локальных переменных куда-то педераете, то сами себе сами знаете кто.
          Ответить
          • знаем, знаем...
            https://youtu.be/0ca8F7SLxiA?t=727
            Ответить
            • Ого, знаменитая лубочная раскраска «Спектрума», где каждый кластер 8×8 раскрашен одним цветом, а меняться может только яркость.

              Для чего так сделали? Экономили видеопамять?
              Ответить
              • Память, конечно.

                Гугли attribute clash (Конфликт атрибутов)
                https://ru.wikipedia.org/wiki/%D0%9A%D0%BE%D0%BD%D1%84%D0%BB%D0%B8%D0%BA%D1%82_%D0%B0%D1%82%D1%80%D0%B8%D0%B1%D1%83%D1%82%D0%BE%D0%B2


                ps: так что не только писюкатые гейдевки ебалися с планарами, спектрумисты еще более ебалися
                Ответить
                • Спасибо. Про MSX и NES не знал.

                  С планарами считай, что ебли нет: любой пиксель можно раскрасить в любой цвет, только на вывод пикселя уходит много тактов из-за планаров (в быстрых играх придётся делать буферизацию и выводить пиксели оптом, чтобы реже переключать планары).
                  Ответить
                  • В игре три космические гуманоидные жабы формируют группу под названием «Боевые жабы». Две «Боевые жабы», Рэш и Зитц, отправляются на миссию по спасению своих похищённых друзей от Темной Королевы — Пимпла и Принцессы Анжелики.
                    Ответить
                    • Мы в школе сбегали с труда чтобы поиграть на денди в баттлтодс!

                      а еще были баттлтодс и даблдрагн
                      Ответить
                      • Училка тоже должна сбегать томущо Анжелика и король
                        Ответить
                        • а еще маркиза ангелов, а королёк -- птичка певчая
                          Ответить
                    • > жабы

                      https://ru.m.wikipedia.org/wiki/Кобыла_и_трупоглазые_жабы_искали_цезию,_ нашли_поздно_утром_свистящего_Хна
                      Ответить
          • ЗАбей на мой высер про self-reference, это тут ВООБЩЕ не причем
            Ответить
      • Не компилится нихуя: https://godbolt.org/z/sxdn94dz9
        Ответить
        • аааааа
          хуясе!

          ты имел ввиду что статический storage нельзя сделать, адля массива можно?

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

          я просто вообще нитак тебя понял
          Ответить
          • Я тоже про локалки подумал.

            Нельзя же в си так структуры инициализировать
            Ответить
        • Через ехтегн робит
          typedef struct ll_node
          {
            struct ll_node *prev;
            struct ll_node *next;
            int val;
          } ll_node;
          
          extern ll_node b;
          extern ll_node c;
          
          ll_node a = {&c, &b, 1};
          ll_node b = {&a, &c, 2};
          ll_node c = {&b, &a, 3};
          
          int main(){
              int k = 0;
              ll_node *i = &a;
              ll_node *j = &c;
              while (k++ <= 6) {
                  printf("i=%d j=%d\n", i->val, j->val);
                  i = i->next;
                  j = j->prev;
              }
          }
          Ответить
          • А если мне нужны статические глобальные переменные?
            Ответить
            • Тогда уж через фнукцию инициализировать
              Ответить
              • А эта функция может как-нибудь в компилтайме отработать?
                Ответить
                • Конечно. Просто генери нужный тебе блоб, и подключи его линкером в секцию. Но мне кажется там надо как-то компилятору правильно лейаут структуры сделать
                  Ответить
              • Ну и вместо массива можно все статические глобалки в специально созданную структуру вхуярить, тогда их можно спокойно друг на друга ссылать
                #include <stdio.h>
                
                typedef struct ll_node
                {
                  struct ll_node *prev;
                  struct ll_node *next;
                  int val;
                } ll_node;
                
                extern ll_node b;
                extern ll_node c;
                
                struct shit
                {
                  ll_node a;
                  ll_node b;
                  ll_node c;
                };
                
                static struct shit my_shit=
                {
                  {&my_shit.c, &my_shit.b,0},
                  {&my_shit.a, &my_shit.c,1},
                  {&my_shit.b, &my_shit.a,2},
                };
                
                int main()
                {
                  ll_node *ptr = &(my_shit.a);
                  for(int i = 0; i < 10; i++)
                  {
                    printf("%d\n", ptr->val);
                    ptr = ptr->next;
                  }
                  return 0;
                }
                Ответить
                • В "Си" почему-то нету ключевого слова "это статическая глобальная переменная, я ее тут просто объявляю, а проинициализирую потом"
                  Ответить
                  • Да вообще не помешала бы forward-декларация.

                    Самое интересное, что для функций такое есть: я могу объявить прототип функции, а реализацию написать ниже.
                    Ответить
                  • Прикинь, сижку подзабыл, в голове один экстрен остался. Ещё такие вариянты деклареций есть:
                    static ll_node b;
                    static ll_node c;
                    
                    static ll_node a = {&c, &b, 1};
                    static ll_node b = {&a, &c, 2};
                    static ll_node c = {&b, &a, 3};
                    
                    
                    // bkb? njkmrj lkz cnherneh
                    
                    
                    ll_node b;
                    ll_node c;
                    
                    ll_node a = {&c, &b, 1};
                    ll_node b = {&a, &c, 2};
                    ll_node c = {&b, &a, 3};

                    https://en.cppreference.com/w/c/language/declarations
                    Ответить
                    • Зато в крестах это не компилируется

                      > error: redefinition of 'll_node b'
                      Ответить
                      • Какой багор )))

                        А нестандартные расширения на этот случай есть типа __attribute__ в гцц и в Шланге?
                        Ответить
    • ахаха (тут про трампов и защитников жопы, всё как мы любим)
      https://pbs.twimg.com/media/Gll2uofWwAAAT4S?format=png&name=900x900
      Ответить
    • блядь) гологубный маск сказал, что твиттер положили сегодня заддося его с украинских IP.

      Гост, а что, ddosят хакеры всегда со своего домашенго IP?
      Ответить
      • Разумеется, быстро-быстро жмут F5 или Ctrl+R в браузере, и сайт ложится.

        «Интернет Эксплорер» специально тормозил, чтобы им было трудно уронить сайты.
        Ответить
        • Кстати, я знаю реальные сайты, которые можно положить F5.
          И такие сайты, на которые вдвоём лучше не заходить.
          Ответить
      • Нет, с рабочего
        Ответить
        • Рабочие накручиваются на хую
          начальство довольно
          премия выросла
          Ответить
          • Землю крестьянам, пусть жрут её с голоду
            На погосте место для себя готовят смолоду
            Заводы рабочим от зари до зари
            И чтоб кровавым потом захлебнулись эти твари
            Ответить
    • Однажды программист не обосрался с эскейпингом, и умер
      https://pbs.twimg.com/media/GKEpSauXcAAkDT2?format=jpg&name=small
      Ответить

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