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

    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
    /* --- PRINTF_BYTE_TO_BINARY macro's --- */
    #define PRINTF_BINARY_PATTERN_INT8 "%c%c%c%c%c%c%c%c"
    #define PRINTF_BYTE_TO_BINARY_INT8(i)    \
        (((i) & 0x80ll) ? '1' : '0'), \
        (((i) & 0x40ll) ? '1' : '0'), \
        (((i) & 0x20ll) ? '1' : '0'), \
        (((i) & 0x10ll) ? '1' : '0'), \
        (((i) & 0x08ll) ? '1' : '0'), \
        (((i) & 0x04ll) ? '1' : '0'), \
        (((i) & 0x02ll) ? '1' : '0'), \
        (((i) & 0x01ll) ? '1' : '0')
    
    #define PRINTF_BINARY_PATTERN_INT16 \
        PRINTF_BINARY_PATTERN_INT8              PRINTF_BINARY_PATTERN_INT8
    #define PRINTF_BYTE_TO_BINARY_INT16(i) \
        PRINTF_BYTE_TO_BINARY_INT8((i) >> 8),   PRINTF_BYTE_TO_BINARY_INT8(i)
    #define PRINTF_BINARY_PATTERN_INT32 \
        PRINTF_BINARY_PATTERN_INT16             PRINTF_BINARY_PATTERN_INT16
    #define PRINTF_BYTE_TO_BINARY_INT32(i) \
        PRINTF_BYTE_TO_BINARY_INT16((i) >> 16), PRINTF_BYTE_TO_BINARY_INT16(i)
    #define PRINTF_BINARY_PATTERN_INT64    \
        PRINTF_BINARY_PATTERN_INT32             PRINTF_BINARY_PATTERN_INT32
    #define PRINTF_BYTE_TO_BINARY_INT64(i) \
        PRINTF_BYTE_TO_BINARY_INT32((i) >> 32), PRINTF_BYTE_TO_BINARY_INT32(i)
    /* --- end macros --- */
    
    #include <stdio.h>
    int main() {
        long long int flag = 1648646756487983144ll;
        printf("My Flag "
               PRINTF_BINARY_PATTERN_INT64 "\n",
               PRINTF_BYTE_TO_BINARY_INT64(flag));
        return 0;
    }

    Запостил: govnokod3r, 18 Октября 2019

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

    • Переведи на «PHP».
      Ответить
    • Бопманд оценил бы.
      Ответить
      • printf("My Flag "
                   PRINTF_BINARY_PATTERN_INT64 "\n",
                   PRINTF_BYTE_TO_BINARY_INT64(getchar()));
        Ответить
        • ??
          Ответить
          • Угандай во что раскроется PRINTF_BYTE_TO_BINARY_INT64(getchar())
            Ответить
            • Понил. В 64 гетча.
              Ответить
            • Но точно также с мокросами MIN и MAX.
              Ответить
              • да, это классический анекдот про

                #define MIN(a, b) a < b ? a : b
                ///
                int a = MIN(get_iq(makaka), get_iq(pitux));


                А еще я как-то попытался взять указатель на функцию, а она оказалась макросом
                Я тогда здорово перепугалось
                Ответить
                • #define MIN(a, b) ([](auto x, auto y) { return x < y ? x : y; })((a), (b))
                  Ответить
                  • огосподи, ты создал пунцию и сразу ее вызвал? Это так можно в крестах?

                    в жопаскрипте так делали ранше, чтоб эмоулить модульность
                    Ответить
                    • Так можно, начиная с C++11.

                      Это замыкание.

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

                      По совместительству -- анонимная функция, она же лямбда. По реализации -- что-то типа класса с единственным методом.
                      Ответить
                      • >В квадратных скобках указывается контекст, который нужно захватить

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

                        где еще можно явано сказать, что хватать? в пхп?
                        Ответить
                        • Именно поэтому я за "PHP".
                          Ответить
                        • Довольно запутанно сделали в «Питоне»: вроде есть слова «global» и «nonlocal» (последнее появилось в тройке), но без них всё равно захватывает. Эти слова всего лишь запрещают создавать новую переменную.
                          Ответить
                          • global обращается к переменной уровня модуля (топ-левел). Всегда.
                            nonlocal -- к ближайшей НЕ топлевелной.

                            Это мутно, конечно.

                            Лучше всего сделано в Perl: там есть
                            * переменные уровня пакета (ака глобальные), определяются с ключом our, видны снаружи пакета (через ::), видны в таблице глобов.
                            * переменные лексического скопа, определяются с ключом my, не видны снаружи пакета, видны в рамках блока (блоком может быть файл).

                            То-есть разница между пакетной и лексической видимостью очевидна и явна
                            Ответить
                            • Приведи пример, где тебе в работе реально нужен был Perl.
                              Ответить
                              • Perl не поможет тебе установить Python 3.5 на Windows XP, а следовательно прыщебляди соснули
                                Ответить
                                • Приведи пример, где тебе в работе реально нужен Windows XP.
                                  Ответить
                                  • пидо-рашке болше делать нечего, как обновлять windows? Остальным папа с мамой занимаются?

                                    Серьезные люди без надобности Windows не обновляют.
                                    Ответить
                    • Вот теперь смотри и слушай:
                      https://gcc.godbolt.org/z/u-AYhu

                      Создаётся вот такая "анонимная" функция:
                      _ZZ4mainENKUlT_T0_E_clIiiEEDaS_S0_:
                              push    rbp
                              mov     rbp, rsp
                              mov     QWORD PTR [rbp-8], rdi   ; укококозатель на кокококонтекст
                              mov     DWORD PTR [rbp-12], esi  ; x
                              mov     DWORD PTR [rbp-16], edx  ; y
                              mov     eax, DWORD PTR [rbp-12]
                              cmp     eax, DWORD PTR [rbp-16]  ; x < y ?
                              jge     .L2
                              mov     eax, DWORD PTR [rbp-12]  ; да => возвращаем x
                              jmp     .L4
                      .L2:
                              mov     eax, DWORD PTR [rbp-16]  ; нет => возвращаем  y
                      .L4:
                              pop     rbp
                              ret

                      Способ вызова:
                              lea     rax, [rbp-1]  ; захватываем указатель на FP (не знаю, почему минус один)
                              mov     edx, 7        ; второй аргумент
                              mov     esi, 5        ; первый аргумент
                              mov     rdi, rax      ; нулевой аргумент -- что-то типа this для методов
                                                    ; в данном случае нулевым аргументом передаётся родительский контекст
                              call    _ZZ4mainENKUlT_T0_E_clIiiEEDaS_S0_
                      Ответить
                      • И заметь: никаких трамплинов, в отличие от указателей на вложенные функции в гэцэцэшном расширении сишечки.
                        Ответить
                        • В гнусях вообще-то лямбд нет. Кстати, замыкание != лямбда.

                          В гнусях, вроде, трамплин будет только если возвращать указатель на вложенную функцию (вот это уже замыкание). А так, для простых вложенных функций это нахуй не надо, просто органичит область видимости.
                          Ответить
                          • замыкане захватывает котекст
                            а лямбда это просто онанимная функция
                            Ответить
                          • Кстати, почему не работает ключ -fno-trampolines? Согласно документации gcc при вызове с этим ключом должен вместо трамплинов возвращать хитрый указатель на структуру, описывающую замыкание, который при разыменовании будет подменяться указателем на функцию-диспетчер, устанавливающую контекст и вызывающую вложенную функцию, так что исполнимый стек не понадобится. Однако, в реальности этот ключ тупо игнорируется.

                            Может быть, этот ключ работает только на определённых платформах?
                            Ответить
                            • Трамплины нужны там, где нельзя сделать стек екзекутиблным. А где можно, там наверное он хуй ложит на твой ключ
                              Ответить
                  • inline auto MIN(auto x, auto y) {auto; return x < y ? x : y;
                    Ответить
                  • #define MIN(a, b) ({typeof(a) x = a; typeof(b) y = b; x < y ? x : y;})
                    Ответить
                    • Мне тут птичка напела что в С++ вообще надо использовать inline вместо макросов, эффект будет тот же.
                      Зачем нужны макросы такие?
                      Ответить
                      • inline может не заинлайнитца, если не зафорсить.
                        Ответить
                      • Не тот же, реальный инлайн тебе никто не обещает.

                        Вообще-то и в сях инлайн есть, и генерики, но общим будет только имя, реализацию для разных типов придется писать свою.
                        Ответить
                        • инлайн в си завезли из плюсов:)

                          а генрики конечно есть: передаегшь указатель на войд и авторым парметром тип)

                          по какой причине копулятор может незаинлайнить чото?
                          Ответить
                          • > указатель на войд
                            Я про _Generic.
                            Ответить
                            • Нашёл. Это C11, используется в мокросах для эмуляции перегрузки функций:
                              https://en.cppreference.com/w/c/language/generic

                              #include <stdio.h>
                              #include <math.h>
                               
                              // Possible implementation of the tgmath.h macro cbrt
                              #define cbrt(X) _Generic((X), \
                                            long double: cbrtl, \
                                                default: cbrt,  \
                                                  float: cbrtf  \
                              )(X)
                               
                              int main(void)
                              {
                                  double x = 8.0;
                                  const float y = 3.375;
                                  printf("cbrt(8.0) = %f\n", cbrt(x)); // selects the default cbrt
                                  printf("cbrtf(3.375) = %f\n", cbrt(y)); // converts const float to float,
                                                                          // then selects cbrtf
                              }
                              Ответить
                          • Компилятору может показаться, что твоя функция слишком большая, поэтому если её заинлайнить в несколько мест, то код сильно раздуется. Тогда он не будет инлайнить.
                            Ответить
                    • Лол. Как это работает?
                      Ответить
                      • Это гэцэцизм:
                        1. typeof на этапе компиляции извлекает из выражения его тип. Что-то типа auto в новых крестах.

                        2. Фигурные скобки ограничивают блок. Блок может возвращать значение (почти как в скриптовых языках): берётся значение последней операции.

                        3. Ну и круглые скобки на всякий случай, чтобы показать, что нужно извлечь значение выражения.

                        За пределами gcc это всё работать не обязано.
                        Ответить
                        • Спасибо за столь подробный ответ, инканусинхо.

                          В каких ещё языках, кроме "R", возвращаемое значение - значение последней операции?

                          MIN = function (a, b) {
                             ifelse(a < b, a, b)
                          }
                          Ответить
                          • Навскидку: Javascript и Ruby.
                            Ответить
                            • В JavaScript как, инканусян?
                              Ответить
                              • Было трудно, но я вспомнил: это работает только внутри эвала:
                                var x = eval('{3; 5; 7;}');
                                alert(x); // выведет 7
                                Ответить
                          • Groovy
                            Ответить
                            • Пойдёшь с нами в бар, посрать++?
                              Ответить
                            • Груви умер к сожалению (если не считать гредл), а жаль.

                              Мне так не хватает GPath и ast transformation
                              Ответить
                              • Да вот нет. Достали, смахнули паутину и юзаем в проекте 2019 года, где из жабки надо запускать однострочные скрипты, работающие над объектами, коллекциями. Ибо жс там соснул и в целом с жавой дружит все меньше.
                                Отлично груви зашёл, рекомендую.
                                Ответить
                                • Я пидорас
                                  Ответить
                                  • Крутится рулетка
                                    Играет джаз
                                    Крутится рулетка
                                    Играет джаз
                                    Крутится рулетка
                                    Играет джаз

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

                                  Кстати, почему?
                                  Идея же очень хорошая.
                                  Вот я сделал ужасный энтерпрайз, на чем мне писать высокоуровневую бизнес логику и скрипты автоматизации?

                                  Почему вообще так мало внимания грейлсу? Маркетинг?
                                  Ответить
                                  • если грейлс - это сорт говна, который рендерит хтмл на стороне бека, по аналогии с RoR, то нахуй он не нужен, и не откапывайте
                                    Ответить
                                    • Да, примерно оно есть, как и джанго например.

                                      Бывает очень удобно, когда нужно быстро написать тупой сайт.

                                      Это лучше, чем делать весь этот бойлерплейт вручную.
                                      Ответить
                                      • > Бывает очень удобно, когда нужно быстро написать тупой сайт.

                                        АХАХАХАХАХАХ
                                        Ответить
                                    • По аналогии с "PHP".
                                      Ответить
                          • Ruby
                            Ответить
                  • Code golf:
                    #define MIN(a,b) ([x=(a),y=(b)](){return x<y?x:y;})()


                    https://gcc.godbolt.org/z/Coc9oy

                    https://ideone.com/tfrPdX
                    Ответить
                    • А вызов теперь выглядит так:
                      mov     DWORD PTR [rbp-8], 5
                      mov     DWORD PTR [rbp-4], 7 ; расталкиваем аргументы по локальным переменным
                      lea     rax, [rbp-8]
                      mov     rdi, rax ; в функцию передаём только указатель на начало блока локальных переменных
                      call    main::{lambda()#1}::operator()() const

                      Вероятно, нечётное значение указателя в примере с пустыми квадратными скобками означало, что ничего не захвачено.

                      Кстати, уже с -O1 в обоих примерах всё инлайнится и заменяется на вычисленную в компайлтайме константу.
                      Ответить
                    • #define MIN(a, b) std::min(a, b)
                      Ответить
                  • При таком определении на каждый вызов будет создаваться новая лямбда, если не включить оптимизацию. Пример:
                    int main() {
                        std::cout << MIN(5, 7) << std::endl;
                        std::cout << MIN(7, 5) << std::endl;
                        return 0;
                    }
                    Компилятор создаст две совершенно одинаковые реализации лямбды. А если вызов MIN использовать много раз, то будет какой багор.

                    Да, при включенной оптимизации, если аргументы являются константами, компилятор лямбду выкинет и заменит на результат. А если аргументы переменные, всегда ли он сможет оптимизировать?
                    Ответить
            • ДЛЯ ТОГО МАКРОСЫ БОЛЬШИМИ БУКВАМИ И ПИШУТ, ЧТОБЫ ДЕРЖАТЬ С НИМИ ХУХО ВОСТРО.
              Ответить

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