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

    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
    30. 30
    31. 31
    32. 32
    33. 33
    34. 34
    35. 35
    36. 36
    37. 37
    38. 38
    39. 39
    40. 40
    41. 41
    #include <stdio.h>
    #include <stdlib.h>
    
    typedef struct {
      int field1;
      int field2;
    } teststr;
    
    typedef struct {
      char data[sizeof(teststr)];
    } teststr_holder __attribute__ (( aligned (__alignof__ (teststr)) ));
    
    typedef union {
      teststr n1;
      teststr_holder n2;
    } str_conv;
    
    int field1_get(teststr_holder a)
    {
      str_conv cnv = {.n2 = a};
      return cnv.n1.field1;
    }
    
    int field2_get(teststr_holder a)
    {
      str_conv cnv = {.n2 = a};
      return cnv.n1.field2;
    }
    
    teststr_holder init_teststr(int field1, int field2)
    {
      str_conv cnv = {.n1 = {field1, field2}};
      return cnv.n2;
    }
    
    int main(void)
    {
      teststr_holder a = init_teststr(1234, 5678);
      printf("%d %d\n", field1_get(a), field2_get(a));
      return EXIT_SUCCESS;
    }

    Какое сокрытие )))

    Запостил: j123123, 09 Мая 2020

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

    • А если так:
      int field1_get(teststr_holder a)
      {
        teststr *cnv = (teststr *)a.data;
        return cnv->field1;
      }
      
      int field2_get(teststr_holder a)
      {
        teststr *cnv = (teststr *)a.data;
        return cnv->field2;
      }

      нет ли тут UB?
      Ответить
      • Дык в сишке обычно вместо холдера void*
        Ответить
        • void нелья передать по значению и нельзя выделить на стеке
          Ответить
          • да, интересно было бы посмотретьь на sizeof(void)
            Ответить
      • Да вроде норм, char* можно алиасить с чем угодно.
        Ответить
        • Древние сишники не знали слова "void*", и использовали вместо него char*, по сути имея ввиду "указатель байт".

          void* завезли в c89 кажется, в K&R его не ьыло
          Ответить
          • древние сишники писали на перфорированных глиняных табличках
            Ответить
          • вообще нифиг приплетать древних - раньше было лучше
            Ответить
            • раньше было лучше, да
              потом понарадился всякий скрипторак
              Ответить
    • Ну да, любой кусок памяти можно считать/записать как произвольный тип. Юнион позволяет это делать без явных кастов, но тоже не вижу принципиальных различий с кастом в void*. Если уж так надо именно на стеке аллоцировать (чтобы, например, передавать в функции), то можно завести всякие concealer1b_t, concealer2b_t, concealer3b_t и делать всё тот же каст.
      Ответить
    • Я понимаю зачем это делают в крестах, чтобы конструкторы и деструкторы автоматом не стреляли. Но в сишке то нафига?

      З.Ы. Инкапсуляция? Но у тебя sizeof/alignof не скомпилятся не увидев структуру. Т.е. она один фиг в паблик торчит.
      Ответить
      • Ну вообще можно через некое говно генерить хедер, в котором будет эта фигня подставлена в виде цифры, без всяких там sizeof/alignof.
        Ответить
        • > генерации

          Сишники плакали, кололись, но продолжали генерить обвес для инкапсуляции и полиморфизма.
          Ответить
          • и самое главное -- зачем?

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

              Не работает это так. Всем насрать, что они не документированы.

              Уже сколько примеров было, когда софт юзал структуры из опенсурсных либ напрямую, а авторам либ приходилось свои правки откатывать и тащить совместимость дальше.

              Юзерам похуй кто был прав, а кто писал говно. Посыпалась куча софта после обновления либы - значит либа виновата.
              Ответить
              • то-есть все программисты -- тупые безграмотные ебланы, не могущие отличить API внутренних кишок реализации?
                Ответить
                • Ну… Вообще-то да.
                  Ответить
                • Обычно есть варианты: залезть в кишки снаружи или форкнуть и залезть в кишки внутри
                  Ответить
                  • Да все проще. Структура вот она, в хедере, все поля видно. Кто будет заморачиваться и искать какие-то функции для работы с ней.

                    А private то не завезли.
                    Ответить
                    • можно static заюзать, но это ж блядь сам в других файлах не сможешь использовать
                      Ответить
                      • Статик на структуре? Лолшто.
                        Ответить
                      • погуглил, кажется, тип нельзя застатизировать. какая гомогенность )))
                        Ответить
                        • статик (в данном случае) влияет на линковку символа
                          тип это не символ и он не линкуеца же
                          Ответить
                          • ага, я просто в прошлый прочитал, что это "кейворд, который определяет видимость в пределах файла", и подумал что это реально кейворд, который создан для определения видимости (а не вот этого вот)
                            Ответить
                            • static имеет два значения в си:

                              * static внутри фукнции влияет на время жизни. Он живет вечно, но доступен только внутри функции (примерно как статическое приватное поле в жабах и шарпах)
                              * static на топлевеле запрещает доступ к символу из других единиц трансляции
                              Ответить
                          • показать все, что скрытоvanished
                            Ответить
                            • ты так и не объяснил, каким образом я стертор
                              Ответить
                              • Я бы на твоём месте гордился. Стертор бывает у собак, а они лучше людей.
                                Ответить
                    • ну так тогда и скриптушня вся соснула
                      Ответить
                      • Это ее обычное состояние
                        Ответить
                      • Ну да. Но они уже привыкли и просто получают удовольствие от процесса. А сишники все пытаются сковородочкой прикрыться.
                        Ответить
                        • Кажется что от говнососа все равно не укроешся: этот дебил может на случайное поведение завязаться, и всё равно все сломается.
                          Лучше уже ничего не закрывать: завязался на говно -- сам себе злобный.

                          Это не работает когда ты Торвальдс, но мы не торвальдсы
                          Ответить
                    • А в виндовый HWND лазил кто?
                      Ответить
                      • HWND это алиас для HANDLE.

                        А HANDLE это смещение в таблице хендлов процесса (в структуре EPROCESS кажется).

                        Вроде бы примерно так, но могу наврать
                        Ответить
                        • Идеальная инкапсуляция. Если еще и через сисколы, то бесподобно
                          Ответить
                          • Не понял. Что через сисколы?

                            Кстати, сисколы в винде не документированы: API винды это Win32API (и частично NativeAPI, только в документированных местах). Это не линукс, где сисколы и их ABI рок солид
                            Ответить
                      • Тут динамическая аллокация ну или слоты в табличке. С ней то без проблем инкапсулируется. Но j123123 хочет чтобы стек и пирфоманс, как с private в крестах.
                        Ответить
          • А крестовики через руби генерят обвес для своего говнобуста https://govnokod.ru/26520#comment535565

            https://govnokod.ru/23287#comment389547
            > Тоесть, смотрите, как ведет себя настоящий, состоявшийся, знающий себе цену программист? А он ведет себя очень просто: плюсы - говно, но и си - говно, кричит он громко, ничуть не смущаясь подходящих к нему слева - одептов плюсов, а справа - почетателей битоебского низкоуровневого язычка типа Си
            Ответить
            • А вот в Ди... можно генерить код на Ди прямо во время компиляции. И хана этой Hana
              Ответить
          • Кстати, а чем крестошаблонопарашная генерация принципиально лучше, чем обычная текстовая генерация, когда некий код на одном языке высирает валидный код на другом языке? Тем, что там какая-то типобезопасность от этого шаблоноговна появляется? Так эту типобезопасность можно и в свой текстовый говногенератор встроить. К тому же вот конкретно шаблонопарашная генерация намертво привязана к говноязыку C++ и ни под что другое ее не заюзать, а вот если я говнотекстовую генерацию сделаю, которая высирает код на Си, то будет не так уж сложно перенести генерацию на какую-нибудь Java или C#. Ну и крестошаблонопарашной говногенерации самой по себе иногда недостаточно, и в Hana применили еще и говнотекстовую генерацию, см. ссылку выше.

            Так что крестоговно сосет
            Ответить
            • Тем, что для внешней текстовой генерации надо будет пилить полный анализатор крестокода, с этими вашими «SFINAE», «CRTP» и прочим метаговном.

              UPD: ну и собирать единый язык проще. Добавлять в сборку лишний этап — геморрой.
              Ответить
              • > Тем, что для внешней текстовой генерации надо будет пилить полный анализатор крестокода, с этими вашими «SFINAE», «CRTP» и прочим метаговном.

                Не факт. Свой генератор я могу написать через какие-нибудь гомоиконы, и там этой крестопараши не будет
                Ответить
                • Ну хорошо, вот реальный пример:
                  template<typename T1, typename T2>
                  auto add(T1 a, T2 b) { return a + b; }
                  // где-то ещё
                  int a = add(40, 2);
                  double b = add(a, 40.5);


                  Для достижения аналогичного результата твоему генератору на гомоиконах в любом случае придётся проанализировать весь крестокод, найти вызовы add(), вычислить типы аргументов и сгенерировать две специализации — add<int, int> -> int и add<int, double> -> double. И это ещё самый простой пример.
                  Ответить
                  • Пфф... анализ типопетушни это вообще отдельная тема. Ну можно экстрактить инфу о том, какое там говно передается в какую-то парашу, потом на основе этой ссанины делать вывод о том, кодохуерируем ли мы вызов add_int_int(int a, int b) или add_int_float(int a, float b) и это конечно довольно-таки заебаная хуйня, вычленять из кода какую-то дрисню руками, надо по-сути кусок компилятора реализовать в кодогенераторе, наверное через какую-нибудь хуйню из clang можно это сделать относительно легко.

                    Я вообще о другой хуйне. Вот хотим мы делать кодохуерацию не только в Си, но и в Java допустим, а там типопитушня отличается. Какие есть предложения? Ну если надо чтоб хуйня с такими типами превращалась в вызов того говна, а хуйня с другими типами - в вызов другого, можно дрочиться с каким-то говном, умеющим анализировать код, чтобы смотреть, тот ли тип мы в такую-то поебень передаем, или не тот (при этом отдельно дрочиться в Си, отдельно в жабе), а можно тупо не завязываться на языковую типопитушню, и просто генерить код, реальный пример: https://govnokod.ru/23246#comment388906
                    Ответить
                    • А, ты про это… Ну дак просто возьми PHP и всё, он как раз для такого предназначен.
                      Ответить
                      • > Ну дак просто возьми PHP

                        Настоящие Цари не опускаются до такого анскильного говна
                        Ответить
                  • И например можно ли представить на крестопараше некую поебень, которая бы компилировалась в то или иное говно, в зависимости от того, сколько раз используется оператор if() в той функции, в которой то говно вставлено?

                    Что-то типа
                    int test(void)
                    {
                      if (TRUE)
                      {}
                      if (TRUE)
                      {}
                      return __count_ifs(); // вернет 2
                    }
                    
                    int test1(void)
                    {
                      return __count_ifs(); // вернет 0
                    }
                    
                    int test2(void)
                    {
                      return __count_ifs(); // вернет 1
                      if (TRUE)
                      {}
                    }

                    Средствами крестоговна такое просто нельзя реализовать, разве что написать нахуй парсер крестов в constexpr и через парашу типа std::embed https://govnokod.ru/26022 свой же исходник парсить. А через какие-то костыли через clang какой-нибудь можно сделать намного проще.
                    Ответить
              • Кривые ублюдочные костыли на смеси препроцессора, шаблонов, констэкспров и кодогенерации - основной и пожалуй единственный способ увеличения уровня абсракции в ублюдских крестах.

                Говностандартизаторы могут конечно насрать в стандарт нового говна, и тогда арсенал немного увеличится, но предыдущие компоненты говнорецепта остаются теми же.
                Ответить
                • Тупо нагенерируй перегрузки функции add для разных предопределенных типов. Нужны будет новые типы - пользователь пропишет в скрипт генерации. Дешево и сердито.
                  Ответить
                  • Не-а, не катит. Так SFINAE эмулировать не получится, а без него это бессмысленно.
                    Ответить
            • вы мой кумир
              Ответить

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