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

    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
    #include <stdio.h>
    
    struct{int a; float b;} test()
    {
      return (typeof(test())){1337, 666.666};
    }
    
    int main()
    {
      auto a = test();
      printf("%d %f\n", a.a, a.b);
      return 0;
    }

    В стандарт C23 добавили auto и теперь можно писать такую хуйню. В "Clang" работает: https://godbolt.org/z/GG3addqPb

    Запостил: j123123, 17 Июня 2025

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

    • А вот в "GCC" - хуй там https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116631
      Ответить
      • Однако если "auto" заменить на "__auto_type", в GCC будет работать. Какой багор )))
        Ответить
        • Значит, в GCC теперь два «auto» с разным поведением на некоторых типах?
          Ответить
          • Да.
            Ответить
            • аУто стандартаки

              а мржно пейсать auto auto(auto auto)?
              Ответить
              • В Си функция не может "принимать" auto
                Ведь если какой-то петух напишет допустим
                int square(auto num) {
                    return num * num;
                }

                то кто-то может вызвать такую говнофункцию с типом "int" а кто-то с типом "double" и это будет две разные функции, а прототип всего один. Короче хуйня какая-то. В Си нет такого, чтоб было несколько функций с одним именем

                И возвращать auto она тоже не может т.к. из прототипа нихуя не ясно, какую хуйню она там может возвращать, и тогда если у нас объявлен лишь прототип
                auto square(int num);
                
                int test()
                {
                  return square(123);
                }

                Компилятору нихуя не будет ясно, какое говно оно вернет. Это тебе даже крестопараша не скомпилирует.

                error: use of 'auto square(int)' before deduction of 'auto'
                Ответить
                • Пичалька
                  Ответить
                • В «C11» есть «_Generic»:

                  #include <stdio.h>
                  #include <stddef.h>
                  #include <stdint.h>
                  
                  #define typename(x) _Generic((x),        /* Get the name of a type */             \
                                                                                                    \
                          _Bool: "_Bool",                  unsigned char: "unsigned char",          \
                           char: "char",                     signed char: "signed char",            \
                      short int: "short int",         unsigned short int: "unsigned short int",     \
                            int: "int",                     unsigned int: "unsigned int",           \
                       long int: "long int",           unsigned long int: "unsigned long int",      \
                  long long int: "long long int", unsigned long long int: "unsigned long long int", \
                          float: "float",                         double: "double",                 \
                    long double: "long double",                   char *: "pointer to char",        \
                         void *: "pointer to void",                int *: "pointer to int",         \
                        default: "other")
                  
                  #define fmt "%20s is '%s'\n"
                  int main() {
                  
                    size_t s; ptrdiff_t p; intmax_t i; int ai[3] = {0}; return printf( fmt fmt fmt fmt fmt fmt fmt fmt,
                  
                       "size_t", typename(s),               "ptrdiff_t", typename(p),     
                     "intmax_t", typename(i),      "character constant", typename('0'),
                   "0x7FFFFFFF", typename(0x7FFFFFFF),     "0xFFFFFFFF", typename(0xFFFFFFFF),
                  "0x7FFFFFFFU", typename(0x7FFFFFFFU),  "array of int", typename(ai));
                  }


                  Увы, можно использовать только в макросах. В функциях нельзя из-за отсутствия перегрузки.
                  Ответить
                  • В «gcc» до «C11» для организации подобного ветвления есть нестандартное расширение __bultins_types_compatible_p:

                    #include <stdio.h>
                    
                    int main(int argc, char **argv) {
                        char *s;
                        if (__builtin_types_compatible_p(__typeof__(s), long)) {
                            puts("long");
                        } else if (__builtin_types_compatible_p(__typeof__(s), char*)) {
                            puts("str");
                        }
                        return (0);
                    };
                    Ответить
              • а в пхп можно
                Ответить
                • В "PHP" не вывод типов, там динамическая питухизация
                  Ответить
                  • Хотя можно конечно придумать некую хуету, чтоб когда вызывается некое говно с какими-то там типами, в рантайме вызывается хуйня которой скармливается тип и некий "AST" или байткод хуиты с этими "auto", и эта хуйня используя JIT генерирует функцию с такими-то типами, но это сложно и не во все контроллеры влезет
                    Ответить
                  • Мало того, что динамическая, она слабая и неявная.

                    «PHP» выводит типы, но во-первых, снаружи ничего не видно (неявность), во-вторых он тут же приведёт тип к другому, если можно (слабость).
                    Ответить
    • Почти OCaml... Только в нём писанины меньше.
      Ответить
    • Почему оно не уходит в рекурсию? Почему вызов typeof(test()) это не вызов?
      Ответить
      • Потому что typeof — это не функция, а конструкция языка, а чтобы посчитать тип, вызывать ничего не надо.

        If the type of the operand is a variably modified type, the operand is evaluated; otherwise, the operand is not evaluated.

        https://en.cppreference.com/w/c/language/typeof.html
        Ответить
        • Сразу захотелось узнать, что такое variably modified type. Оказывается, в сишке это VLA.
          Ответить
        • блядь, я думал семантически это макрос
          Ответить
          • Как ты макрос напишешь, тип возвращающий?
            Ответить
            • я засмеялся: как же я макрос напишу, когда ты их всех
              Ответить
    • Ура! Теперь можно лекго и не задумываясь писать указатели на указатели на функции принимающие указатели на функции возвращающие указатели на указатели на функции возвращающие указатели на функции принимающие указатели на функции...
      Ответить
    • Сорок лет назад auto в си значило совсем иное
      Ответить
      • > Сорок лет
        https://www.youtube.com/watch?v=58Eff70zgjQ
        Ответить
        • Они ушли
          Чеченская Гитара•3,7 млн просмотров

          10 признаков того, что ВЫ ОДНОВРЕМЕННО думаете друг о друге Карл Юнг
          Юнгианка
          Новинка
          1,8 тыс. просмотров
          Ответить
        • я не шучу, кстати

          в древней сишке надо было указывать: лежит переменная на стеке (тн "автоматическая") или в регистре. И там `auto` означала "автоматическая".

          Потом это стало поведением по умолчанию, и это слово убрали.
          Ответить
          • E6amb TbI . SMALL!
            Ответить
          • Ты ещё рааскажи как int перед именем необязательно было писать.

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

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