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

    −46

    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
    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
    #include <stdio.h>
    
    #define SPLICE(a,b) SPLICE_1(a,b)
    #define SPLICE_1(a,b) SPLICE_2(a,b)
    #define SPLICE_2(a,b) a##b
     
     
    #define PP_ARG_N( \
              _1,  _2,  _3,  _4,  _5,  _6,  _7,  _8,  _9, _10, \
             _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, \
             _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, \
             _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, \
             _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, \
             _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, \
             _61, _62, _63, N, ...) N
     
    /* Note 63 is removed */
    #define PP_RSEQ_N()                                        \
             62, 61, 60,                                       \
             59, 58, 57, 56, 55, 54, 53, 52, 51, 50,           \
             49, 48, 47, 46, 45, 44, 43, 42, 41, 40,           \
             39, 38, 37, 36, 35, 34, 33, 32, 31, 30,           \
             29, 28, 27, 26, 25, 24, 23, 22, 21, 20,           \
             19, 18, 17, 16, 15, 14, 13, 12, 11, 10,           \
              9,  8,  7,  6,  5,  4,  3,  2,  1,  0
     
    #define PP_NARG_(...)    PP_ARG_N(__VA_ARGS__)    
     
    /* Note dummy first argument _ and ##__VA_ARGS__ instead of __VA_ARGS__ */
    #define PP_NARG(...)     PP_NARG_(_, ##__VA_ARGS__, PP_RSEQ_N())
    
    
    #define MAX_1(VAR, ...) \
      VAR
     
    #define MAX_2(VAR, ...) \
      (((VAR)>MAX_1(__VA_ARGS__))?(VAR):MAX_1(__VA_ARGS__))
     
    #define MAX_3(VAR, ...) \
      (((VAR)>MAX_2(__VA_ARGS__))?(VAR):MAX_2(__VA_ARGS__))
     
    #define MAX_4(VAR, ...) \
      (((VAR)>MAX_3(__VA_ARGS__))?(VAR):MAX_3(__VA_ARGS__))
     
    #define MAX_5(VAR, ...) \
      (((VAR)>MAX_4(__VA_ARGS__))?(VAR):MAX_4(__VA_ARGS__))
     
    #define MAX_6(VAR, ...) \
      (((VAR)>MAX_5(__VA_ARGS__))?(VAR):MAX_5(__VA_ARGS__))
     
    #define MAX_7(VAR, ...) \
      (((VAR)>MAX_6(__VA_ARGS__))?(VAR):MAX_6(__VA_ARGS__))
     
    #define MAX_8(VAR, ...) \
      (((VAR)>MAX_7(__VA_ARGS__))?(VAR):MAX_7(__VA_ARGS__))
     
    #define MAX_9(VAR, ...) \
      (((VAR)>MAX_8(__VA_ARGS__))?(VAR):MAX_8(__VA_ARGS__))
     
    #define MAX_10(VAR, ...) \
      (((VAR)>MAX_9(__VA_ARGS__))?(VAR):MAX_9(__VA_ARGS__))
     
    #define MAX_11(VAR, ...) \
      (((VAR)>MAX_10(__VA_ARGS__))?(VAR):MAX_10(__VA_ARGS__))
    //..... дальше лень ...
     
    #define MAXS_(N, ...) \
      SPLICE(MAX_, N)(__VA_ARGS__)
     
    #define MAXS(...) \
      MAXS_(PP_NARG(__VA_ARGS__), __VA_ARGS__)
    
     
    int main(void)
    {
     printf("%d", MAXS(24, 324, 377, 347, 100500, 2442, 224, 7428));
    }

    Макрос MAXS() который принимает произвольное число аргументов и через тернарники заворачивает их, было сделано на основе http://govnokod.ru/14511 говна.

    Запостил: j123123, 27 Октября 2016

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

    • показать все, что скрытоMAXS(6,5,4,3,2) разворачивается в такую хрень:
      (((6)>(((5)>(((4)>(((3)>2)?(3):2))?(4):( ((3)>2)?(3):2)))?(5):(((4)>(((3)>2)?(3): 2))?(4):(((3)>2)?(3):2))))?(6):(((5)>((( 4)>(((3)>2)?(3):2))?(4):(((3)>2)?(3):2)) )?(5):(((4)>(((3)>2)?(3):2))?(4):(((3)>2 )?(3):2))))
      Ответить
    • как на с++14 написать вариадик темплейт constexpr-функции, вычисляющей то же самое?
      на с++17 слишком просто
      Ответить
      • бустформатеры решили не юзать вариадиктемплейт, тк получается слишком торнозно и ресурсоемко. Вангую это будет иметь меньшие требования
        Ответить
        • Вариадик темплейт будет инстанцироваться за O(N), а эта макро петушняшня O(2^N), пусть и с меньшей константой.
          Ответить
      • Дык элементарно же. Базовые упражнения на метушню.
         
        #include <iostream>
        
        template<typename T>
        constexpr T tmax(T&& t)
        {
          return std::forward<T>(t);
        }
        
        template<typename T1, typename T2, typename... Numbers>
        constexpr decltype(auto) tmax(T1&& v1, T2&& v2, Numbers&&... rest)
        {
          if (v1 > v2)
            return tmax(v1, std::forward<Numbers>(rest)...);
          else
            return tmax(v2, std::forward<Numbers>(rest)...);
        }
        
        
        int main()
        {
            constexpr int a = tmax(1, 3, 5, 4);
            
            std::cout << a << '\n';
            int x = 5;
            int y = 3;
            int z = 7;
            tmax(x, y, z) = 0;
            std::cout << x << ' ' << y << ' ' << z << '\n';
        }


        EDIT: Не поверите, constexpr забыл.
        Ответить
      • > как на с++14 написать вариадик темплейт constexpr-функции
        Ну если потребовать один тип у всех аргументов max, то вроде даже на C++11 несложно:
        #include <iostream>
        
        template <typename T>
        constexpr T max(T t) { return t; }
        
        template <typename T, typename... Args>
        constexpr T max(T t1, T t2, Args... args) {
          return t1 > t2 ? max(t1, args...) : max(t2, args...);
        }
        
        int main() {
          std::cout << "Max(1): " << max(1) << "\n";
          std::cout << "Max(2): " << max(100, 1) << "\n";
          std::cout << "Max(8): " << max(24, 324, 377, 347, 100500, 2442, 224, 7428) << "\n";
          return 0;
        }
        Ответить
        • правильно через std::max - он промоутит тип, ели надо
          Ответить
          • поясни
            Ответить
            • - If either operand is of type long double, the other shall be converted to long double.
              - Otherwise, if either operand is double, the other shall be converted to double.
              - Otherwise, if either operand is float, the other shall be converted to float.
              - Otherwise, the integral promotions shall be performed on both operands.
              - Then, if either operand is unsigned long the other shall be converted to unsigned long.
              - Otherwise, if one operand is a long int and the other unsigned int, then if a long int can represent all the values of an unsigned int, the unsigned int shall be converted to a long int; otherwise both operands shall be converted to unsigned long int.
              - Otherwise, if either operand is long, the other shall be converted to long.
              - Otherwise, if either operand is unsigned, the other shall be converted to unsigned.

              [Note: otherwise, the only remaining case is that both operands are int]
              Ответить
          • > правильно через std::max

            Если посмотреть в сигнатуру std::max, видно, что он практически не отличается от того, что мы тут написали, и более магическими свойствами обладать не может. Далее, constexpr он стал только в c++14.
            И вообще я его не люблю, он ссылку на аргумент возвращает. Прекрасный способ выстрелить себе в ногу.
            Ответить
            • built-in функции оптимизируются как constexpr даже без обозначения их в качестве таковых. По кр мере с sin/cos/пр. это так. Плюс, вопрос был как раз про с++14.
              Ответить
              • > built-in функции оптимизируются как constexpr даже без обозначения их в качестве таковых

                В стандарте это где-то написано? Что такое built-in функции?
                Ответить
                • Видимо интринсики, которые в gcc называют built-in.

                  > В стандарте
                  Настоящие цари затачивают код под фишки конкретного конпелятора.
                  Ответить
                  • показать все, что скрытоНастоящие цари делают свой процессор и пишут под него в машинных кодах
                    Ответить
                    • > делают свой процессор
                      Дороговато выйдет... Или просто под FPGA синтезируют?
                      Ответить
                      • показать все, что скрытоFPGA для анскиллябр заедушных. Их делают по слишком большому техпроцессу, малая тактовая частота, неоптимально все устроено (какие-то стыкующиеся с друг другом перепрограммируемые ячейки http://www.compitech.ru/html.cgi/arhiv/03_03/stat_108.htm вместо того, чтобы четко и дерзко захаркдкодить топологию аппаратно). В общем это все для анскиллябр, не могущих себе позволить нормальный процессор сделать
                        Ответить
                        • показать все, что скрытоКроме того, эти FPGA не в 3D, как вот тут https://habrahabr.ru/company/intel/blog/118816/
                          Вообще, настоящие цари не хотят ограничиваться 3D пространством при создании процессора. Настоящие цари создадут особое устройство, способное открывать портал в параллельные измерения, с большей пространственной размерностью, более высокой скоростью света и более подходящими физическими законами для создания идеального неанскильного процессора.
                          Ответить
                          • Вообще, пространство отрицательной кривизны должно хорошо подходить для царского процессора. Объём экспоненциально по расстоянию растёт, можно больше ячеек запихнуть.
                            Ответить
                          • По той ссылке в 3D только отдельный транзистор, а не сам процессор. Процессоры же, хоть и бывают многослойными, но всё-таки до сих пор используют третье измерение не на всю мощь.

                            Кстати, мне понравились некоторые ссылки из статьи:
                            https://geektimes.ru/post/256758/
                            https://geektimes.ru/post/256792/

                            Для настоящих царей.
                            Ответить
                            • Барс забил, походу, на этот проект?
                              Ответить
                              • Или пришёл к успеху и держит в секрете от конкурентов.

                                «Писать мне лучше на email: [email protected]»
                                «Сайт: http://3.14.by»

                                Кто знает, над чем я ржу?
                                Ответить
                              • Смотри, что откопал:
                                http://3.14.by/ru/read/KR580VM80A-intel-i8080-verilog-reverse-engineering

                                Туда ещё вложена пэдээфка со схемой (4758 транзисторов).
                                Ответить
                                • > 4758 транзисторов
                                  Прикольно, там даже не КМОП, все транзисторы одинаковые, n-канальные...
                                  Ответить
                              • Ещё вот это расследование у Барса порадовало:
                                http://zeptobars.com/ru/read/FTDI-FT232RL-real-vs-fake-supereal

                                Китайцы в данном случае не просто сделали "фейк", а взяли готовый программируемый маской при производстве микроконтроллер (так нужно менять только одну маску - это намного дешевле и объясняет лишние контакты на кристалле) и заказали изготовление партии этих микросхем на заводе.
                                Ответить
        • Если один тип аргумента, можно вообще использовать std::initializer_list перегрузку std::max:
          template <typename ...Args>
          constexpr auto maxOf(Args ... args) {
              return std::max({args...});
          }
          Ответить

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