1. Список говнокодов пользователя j123123

    Всего: 332

  2. Си / Говнокод #15638

    +134

    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
    
    /* A C statement or statements which output an assembler instruction
       opcode to the stdio stream STREAM.  The macro-operand PTR is a
       variable of type `char *' which points to the opcode name in its
       "internal" form--the form that is written in the machine description.
    
       GAS version 1.38.1 doesn't understand the `repz' opcode mnemonic.
       So use `repe' instead.  */
    
    #undef ASM_OUTPUT_OPCODE
    #define ASM_OUTPUT_OPCODE(STREAM, PTR)	\
    {									\
      if ((PTR)[0] == 'r'							\
          && (PTR)[1] == 'e'						\
          && (PTR)[2] == 'p')						\
        {									\
          if ((PTR)[3] == 'z')						\
    	{								\
    	  fputs ("repe", (STREAM));					\
    	  (PTR) += 4;							\
    	}								\
          else if ((PTR)[3] == 'n' && (PTR)[4] == 'z')			\
    	{								\
    	  fputs ("repne", (STREAM));					\
    	  (PTR) += 5;							\
    	}								\
        }									\
      else									\
        ASM_OUTPUT_AVX_PREFIX ((STREAM), (PTR));				\
    }

    Костыль из GCC. Ассемблер GAS версии 1.38.1 не переваривает мнемоники repz и repnz. Эта макрохрень перекодирует их в repe и repne соответственно
    https://github.com/mirrors/gcc/blob/master/gcc/config/i386/gas.h#L81

    j123123, 02 Апреля 2014

    Комментарии (1)
  3. Си / Говнокод #15628

    +136

    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
    #include <stdio.h>
    #include <inttypes.h>
    
    inline uint8_t mid_ch (uint8_t a, uint8_t b, uint8_t res)
    {
      if (b == 0){ if (a >= 2) return mid_ch (a-2, b  , res+1); else return res;}
      if (a == 0){ if (b >= 2) return mid_ch (a  , b-2, res+1); else return res;}
      return mid_ch (a-1, b-1, res+1);
    }
    
    uint64_t mid_0_ch (uint64_t a, uint64_t b)
    {
      return mid_ch(a, b, 0);
    }
    
    
    int main(void)
    {
      printf("%u %u", mid_0_ch (253, 123), (253+123)/2);
      return 0;
    }

    Нахождение среднего арифметического двух чисел через рекурсию. Сначала сделал для uint64_t чтобы это имело смысл, ведь сложение двух 64-битных чисел с записью результата в третье может привести к целочисленному переполнению (для 64-битных чисел, сложение которых может привести к переполнению, этот код работал чрезвычайно медленно, поэтому я ограничился 8-битными). При таком наркоманско-рекурсивном алгоритме этого переполнения не будет. 128-битные типы есть только как нестандартное расширение, но тогда еще возникает вопрос, как найди среднее арифметическое двух таких 128-битных чисел? А если есть 256-битные, то как тогда их них находить среднеарифметическое... ну и так далее.
    Можно эту проблему еще решать через битовые маски т.е. убрать из обеих чисел самые старшие биты (предварительно сохранив их), сложить эти два числа, поделить на два, потом уже эти сохраненные биты вида 10000... или 0000... оба поделить на 2(сдвинуть на один разряд) и прибавить. Наркоманство какое-то.
    Почему бы не сделать в С некий особый целочисленный тип, в котором любая фигня влезет, но который бы использовался только временно для промежуточных вычислений, чтобы не делать бэкапы битиков всяких?

    j123123, 31 Марта 2014

    Комментарии (22)
  4. Assembler / Говнокод #15415

    +145

    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
    global _start
    
    section .text
    
    _start:
    
    	mov	eax, 0b10010100101100110111110110111110
    	;  эти битики будут выведены на печать
    	
    	mov	ecx, 0b00011000000110000001100000011000
    	; Четыре недозаполненных ascii кодов символов '0' или '1', в который из флага переноса заталкивается битик 0 или 1
    
    	%rep 8
    	mov	ebx, ecx
    	%rep    3
    		shr	eax, 1 ; Захавываем битик в флаг переноса
    		rcl	ebx, 1 ; Запихиваем из флага переноса в недозаполненные ascii коды
    		rol	ebx, 7 ; Проматываем на следующий кусок
    	%endrep
    	shr	eax, 1
    	rcl	ebx, 1 ; На последней стадии все то же самое, только проматывать уже не надо
    
    	push ebx ; Теперь все битики всунуты, пихнем содержимое регистра в стек
    	%endrep
    
    
        
    	mov	eax, 04h ; write()
    	mov	ebx, 01h ; stdout
    	mov	ecx, esp ; распечатаем из стека
    	mov	edx, 32  ; 32 символа
    	int	80h
    	
    	mov	eax, 01h ; exit()
    	xor	ebx, ebx ; errno
    	int	80h

    NASM Linux x86
    Суть - вывести содержимое регистра в двоичной системе счисления
    Можно было вместо этой мути использовать CMOVC ( Move if carry (CF=1) ) или еще что-нибудь такое придумать, есть же еще BT, BTS, глаза разбегаются
    ...вообще хрен его знает, какой-то упоротый этот x86 ассемблер, надо бы AVR осваивать, там регистров побольше

    j123123, 10 Марта 2014

    Комментарии (6)
  5. Си / Говнокод #15406

    +142

    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
    static char months [] = "JanFebMarAprMayJunJulAugSepOctNovDecGlk";
    static char dows [] = "SunMonTueWedThuFriSatEar";
    
    
    int dd [] =
    {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    
    void gen_http_date (char date_buffer[29], int time) {
      int day, mon, year, hour, min, sec, xd, i, dow;
      if (time < 0) time = 0;
      sec = time % 60;
      time /= 60;
      min = time % 60;
      time /= 60;
      hour = time % 24;
      time /= 24;
      dow = (time + 4) % 7;
      xd = time % (365 * 3 + 366);
      time /= (365 * 3 + 366);
      year = time * 4 + 1970;
      if (xd >= 365) {
        year++;
        xd -= 365;
        if (xd >= 365) {
          year++;
          xd -= 365;
          if (xd >= 366) {
            year++;
            xd -= 366;
          }
        }
      }
      if (year & 3) {
        dd[1] = 28;
      } else {
        dd[1] = 29;
      }
    
      for (i = 0; i < 12; i++) {
        if (xd < dd[i]) {
          break;
        }
        xd -= dd[i];
      }
    
      day = xd + 1;
      mon = i;
      assert (day >= 1 && day <= 31 && mon >=0 && mon <= 11 &&
          year >= 1970 && year <= 2039);
    
      sprintf (date_buffer, "%.3s, %.2d %.3s %d %.2d:%.2d:%.2d GM",
          dows + dow * 3, day, months + mon * 3, year,
          hour, min, sec);
      date_buffer[28] = 'T';
    }

    Делать имена месяцев и дни недели одной сишной строкой, чтобы потом выводить оттуда по три символа через sprintf, считая оффсет умножением на 3 т.к. имена месяцев и дней недели влазят в три символа
    https://github.com/vk-com/kphp-kdb/blob/ce1ac4fbde2d3b546936ad07d6a748958f6d2198/net/net-http-server.c#L664

    http://roem.ru/2013/07/20/kphp76561/
    >ВКонтактовские "олимпиадники"-чемпионы ACM разработали крайне интересную высоконагруженным сайтам технологию.

    Хреновые какие-то олимпиадники попались, раз неосилили http://ideone.com/IfvBgi

    j123123, 09 Марта 2014

    Комментарии (81)
  6. Си / Говнокод #14511

    +137

    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
    78. 78
    79. 79
    80. 80
    #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 NARG(...)     func(PP_NARG(__VA_ARGS__), __VA_ARGS__)
     
    #define INCR 20
     
    #define FIELD_0(...)
     
    #define FIELD_1(field, ...) \
      INCR+field
     
    #define FIELD_2(field, ...) \
      INCR+field, FIELD_1(__VA_ARGS__)
     
    #define FIELD_3(field, ...) \
      INCR+field, FIELD_2(__VA_ARGS__)
     
    #define FIELD_4(field, ...) \
      INCR+field, FIELD_3(__VA_ARGS__)
     
    #define FIELD_5(field, ...) \
      INCR+field, FIELD_4(__VA_ARGS__)
     
    #define FIELD_5(field, ...) \
      INCR+field, FIELD_4(__VA_ARGS__)
     
    #define FIELD_6(field, ...) \
      INCR+field, FIELD_5(__VA_ARGS__)
     
    #define FIELD_7(field, ...) \
      INCR+field, FIELD_6(__VA_ARGS__)
     
    #define FIELD_8(field, ...) \
      INCR+field, FIELD_7(__VA_ARGS__)
     
    #define FIELD_9(field, ...) \
      INCR+field, FIELD_8(__VA_ARGS__)
     
    #define FIELD_10(field, ...) \
      INCR+field, FIELD_9(__VA_ARGS__)
     
    #define FIELD_11(field, ...) \
      INCR+field, FIELD_10(__VA_ARGS__)
    //..... дальше лень ...
     
    #define FIELDS_(N, ...) \
      SPLICE(FIELD_, N)(__VA_ARGS__)
     
    #define FIELDS(...) \
      FIELDS_(PP_NARG(__VA_ARGS__), __VA_ARGS__)
     
     
    a = { FIELDS('p', 'a', 's', 's', 'w', 'o', 'r', 'd') }

    Примитивное компил-тайм шифрование строки через сишный препроцессор. На выходе получаем

    a = { 20 +'p', 20 +'a', 20 +'s', 20 +'s', 20 +'w', 20 +'o', 20 +'r', 20 +'d' };

    Базируется на http://smackerelofopinion.blogspot.com/2011/10/determining-number-of-arguments-in-c.html

    j123123, 06 Февраля 2014

    Комментарии (18)
  7. Assembler / Говнокод #13931

    +129

    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
    product:
    .LFB34:
            .cfi_startproc
            xor     eax, eax
            test    esi, esi
            je      .L7
            lea     eax, [rsi-1]
            mov     edi, edi
            add     rax, 1
            imul    rax, rdi
    .L7:
            rep
            ret
            .cfi_endproc

    Оптимизациия умножения через рекурсию. Сишный код:

    inline unsigned long int product_0(const unsigned int a, const unsigned int b, const unsigned long int tmp)
    {
    if (b == 0) return tmp;
    return product_0(a, b-1, tmp+a);
    }

    unsigned long int product(const unsigned int a, const unsigned int b)
    {
    return product_0(a, b, 0);
    }

    Распознать умножение (imul) в этой рекурсивной хрени компилятор смог, но при этом как-то через жопу, нагенерировав при этом много лишнего говна.
    gcc version 4.5.1

    j123123, 12 Октября 2013

    Комментарии (69)
  8. Си / Говнокод #13546

    +140

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    #include <stdio.h>
    
    int main()
    {
      printf("test\n");
      
      __asm volatile (".rept 10\n");
      printf("test\n");
      __asm volatile (".endr");
      
      return 0;
    }

    Еще немного поиздевался над GCC. Через ассемблерные вставки, точнее через вставку директивы .rept иногда можно повторить некоторый кусок кода несколько раз. Работает это далеко не всегда
    http://sourceware.org/binutils/docs/as/Rept.html
    Этот .rept по сути просто копипастит кусок кода

    j123123, 04 Августа 2013

    Комментарии (11)
  9. Си / Говнокод #13512

    +130

    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>
    
    int main()
    {
        int a = 5, b = 6;
        void* go;
        go = ( a > b )? &&true1: &&false1;
        goto *go;
    
          true1:
          {
            printf("%i > %i\n", a, b);
            goto next1;
          }
    
          false1:
          {
            printf("%i <= %i\n", a, b);
          }
    
        next1:
    
    
        a = 7;
        go = ( a > b )? &&true2: &&false2;
        goto *go;
        
          true2:
          {
            printf("%i > %i\n", a, b);
            goto next2;
          }
    
          false2:
          {
            printf("%i <= %i\n", a, b);
          }
    
        next2:
        return 0;
    }

    В GCC есть такой экстеншен http://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html
    Можно в goto передавать переменную и можно работать с адресами меток. В сочетании с тернарной условной операцией, этим можно заменить if

    j123123, 30 Июля 2013

    Комментарии (58)
  10. Си / Говнокод #13492

    +122

    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
    #if defined(REG_R1) && !defined(NO_GLOBAL_REG_DECLS)
    GLOBAL_REG_DECL(StgUnion,R1,REG_R1)
    #else
    # define R1 (BaseReg->rR1)
    #endif
    
    #if defined(REG_R2) && !defined(NO_GLOBAL_REG_DECLS)
    GLOBAL_REG_DECL(StgUnion,R2,REG_R2)
    #else
    # define R2 (BaseReg->rR2)
    #endif
    
    #if defined(REG_R3) && !defined(NO_GLOBAL_REG_DECLS)
    GLOBAL_REG_DECL(StgUnion,R3,REG_R3)
    #else
    # define R3 (BaseReg->rR3)
    #endif
    
    #if defined(REG_R4) && !defined(NO_GLOBAL_REG_DECLS)
    GLOBAL_REG_DECL(StgUnion,R4,REG_R4)
    #else
    # define R4 (BaseReg->rR4)
    #endif
    
    #if defined(REG_R5) && !defined(NO_GLOBAL_REG_DECLS)
    GLOBAL_REG_DECL(StgUnion,R5,REG_R5)
    #else
    # define R5 (BaseReg->rR5)
    #endif
    
    #if defined(REG_R6) && !defined(NO_GLOBAL_REG_DECLS)
    GLOBAL_REG_DECL(StgUnion,R6,REG_R6)
    #else
    # define R6 (BaseReg->rR6)
    #endif
    
    #if defined(REG_R7) && !defined(NO_GLOBAL_REG_DECLS)
    GLOBAL_REG_DECL(StgUnion,R7,REG_R7)
    #else
    # define R7 (BaseReg->rR7)
    #endif
    
    ...

    Исходник GHC
    https://github.com/ghc/ghc/blob/master/includes/stg/Regs.h#L147

    j123123, 27 Июля 2013

    Комментарии (39)
  11. Куча / Говнокод #13491

    +125

    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
    slowCallPattern (P: P: P: P: P: P: _) = (fsLit "stg_ap_pppppp", 6)
    slowCallPattern (P: P: P: P: P: _) = (fsLit "stg_ap_ppppp", 5)
    slowCallPattern (P: P: P: P: _) = (fsLit "stg_ap_pppp", 4)
    slowCallPattern (P: P: P: V: _) = (fsLit "stg_ap_pppv", 4)
    slowCallPattern (P: P: P: _) = (fsLit "stg_ap_ppp", 3)
    slowCallPattern (P: P: V: _) = (fsLit "stg_ap_ppv", 3)
    slowCallPattern (P: P: _) = (fsLit "stg_ap_pp", 2)
    slowCallPattern (P: V: _) = (fsLit "stg_ap_pv", 2)
    slowCallPattern (P: _) = (fsLit "stg_ap_p", 1)
    slowCallPattern (V: _) = (fsLit "stg_ap_v", 1)
    slowCallPattern (N: _) = (fsLit "stg_ap_n", 1)
    slowCallPattern (F: _) = (fsLit "stg_ap_f", 1)
    slowCallPattern (D: _) = (fsLit "stg_ap_d", 1)
    slowCallPattern (L: _) = (fsLit "stg_ap_l", 1)
    slowCallPattern (V16: _) = (fsLit "stg_ap_v16", 1)
    slowCallPattern [] = (fsLit "stg_ap_0", 0)

    Исходник GHC
    https://github.com/ghc/ghc/blob/master/compiler/codeGen/StgCmmArgRep.hs#L120

    j123123, 27 Июля 2013

    Комментарии (5)