1. C++ / Говнокод #28841

    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
    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
    auto objs = it.get_objects();
    
                switch(objs.size())
                {
                    case 1:     sent = _out_stream.send_message(objs[0]);
                                break;
                    case 2:     sent = _out_stream.send_message(objs[0], objs[1]);
                                break;
                    case 3:     sent = _out_stream.send_message(objs[0], objs[1], objs[2]);
                                break;
                    case 4:     sent = _out_stream.send_message(objs[0], objs[1], objs[2], objs[3]);
                                break;
                    case 5:     sent = _out_stream.send_message(objs[0], objs[1], objs[2], objs[3], objs[4]);
                                break;
                    case 6:     sent = _out_stream.send_message(objs[0], objs[1], objs[2], objs[3], objs[4], objs[5]);
                                break;
                    case 7:     sent = _out_stream.send_message(objs[0], objs[1], objs[2], objs[3], objs[4], objs[5],
                                                                objs[6]);
                                break;
                    case 8:     sent = _out_stream.send_message(objs[0], objs[1], objs[2], objs[3], objs[4], objs[5],
                                                                objs[6], objs[7]);
                                break;
                    case 9:     sent = _out_stream.send_message(objs[0], objs[1], objs[2], objs[3], objs[4], objs[5],
                                                                objs[6], objs[7], objs[8]);
                                break;
                    case 10:    sent = _out_stream.send_message(objs[0], objs[1], objs[2], objs[3], objs[4], objs[5],
                                                                objs[6], objs[7], objs[8], objs[9]);
                                break;
                    case 11:    sent = _out_stream.send_message(objs[0], objs[1], objs[2], objs[3], objs[4], objs[5],
                                                                objs[6], objs[7], objs[8], objs[9], objs[10]);
                                break;
                    case 12:    sent = _out_stream.send_message(objs[0], objs[1], objs[2], objs[3], objs[4], objs[5],
                                                                objs[6], objs[7], objs[8], objs[9], objs[10], objs[11]);
                                break;
                    case 13:    sent = _out_stream.send_message(objs[0], objs[1], objs[2], objs[3], objs[4], objs[5],
                                                                objs[6], objs[7], objs[8], objs[9], objs[10], objs[11],
                                                                objs[12]);
                                break;
                    case 14:    sent = _out_stream.send_message(objs[0], objs[1], objs[2], objs[3], objs[4], objs[5],
                                                                objs[6], objs[7], objs[8], objs[9], objs[10], objs[11],
                                                                objs[12], objs[13]);
                                break;
                    case 15:    sent = _out_stream.send_message(objs[0], objs[1], objs[2], objs[3], objs[4], objs[5],
                                                                objs[6], objs[7], objs[8], objs[9], objs[10], objs[11],
                                                                objs[12], objs[13], objs[14]);
                                break;
                    case 16:    sent = _out_stream.send_message(objs[0], objs[1], objs[2], objs[3], objs[4], objs[5],
                                                                objs[6], objs[7], objs[8], objs[9], objs[10], objs[11],
                                                                objs[12], objs[13], objs[14], objs[15]);
                                break;
                    case 17:    sent = _out_stream.send_message(objs[0], objs[1], objs[2], objs[3], objs[4], objs[5],
                                                                objs[6], objs[7], objs[8], objs[9], objs[10], objs[11],
                                                                objs[12], objs[13], objs[14], objs[15], objs[16]);
                                break;
                    case 18:    sent = _out_stream.send_message(objs[0], objs[1], objs[2], objs[3], objs[4], objs[5],
                                                                objs[6], objs[7], objs[8], objs[9], objs[10], objs[11],
                                                                objs[12], objs[13], objs[14], objs[15], objs[16], objs[17]);
                                break;
                    case 19:    sent = _out_stream.send_message(objs[0], objs[1], objs[2], objs[3], objs[4], objs[5],
                                                                objs[6], objs[7], objs[8], objs[9], objs[10], objs[11],
                                                                objs[12], objs[13], objs[14], objs[15], objs[16], objs[17],
                                                                objs[18]);
                                break;
                    case 20:    sent = _out_stream.send_message(objs[0], objs[1], objs[2], objs[3], objs[4], objs[5],
                                                                objs[6], objs[7], objs[8], objs[9], objs[10], objs[11],
                                                                objs[12], objs[13], objs[14], objs[15], objs[16], objs[17],
                                                                objs[18], objs[19]);
                                break;
                    default:
                        fprintf(stderr, "error: Too much attached objects (%lu), talk to developer\n", objs.size());
                        return false;
                }
    
                if (!sent)
                {
                    fprintf(stderr, "error: Unable to send message to output pipe\n");
                    return false;
                }

    Меня заставили это сделать, потому что по задумке число вложенных объектов известно на этапе разработки, а у меня - нет.

    Запостил: YpaHeLI_, 31 Августа 2023

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

    • наметапрограмируй
      Ответить
      • Разве такая дрисня в крестопараше может быть наметапрограммирована?
        Вот если б была гомоиконность...

        А еще это можно напрограммировать на ассемблере. Зная соглашения вызовов, можно насрать в стек нужное количество хуиты через цикл (регистров наверняка не хватит)
        Ответить
        • Метапрограммировать можно и на скриптом на питоне

          >насрать в стек нужное количество хуиты через цикл (регистров наверняка не хватит)

          Там вроде первые скокато питухов нужно пхать в реестры, а остатток можно и в ст... хотя нет... нужно насрать в вызывающем стеке и передать указатель
          Ответить
          • > Метапрограммировать можно и на скриптом на питоне

            Ваша система сборки не это поддерживает? Я в своих говнах могу запускать произвольную программу для препроцессора. Генерю лапшу для крестов на крестах и на питоне.
            Ответить
            • Смотря в каком проекте.

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

              В джаваговне метапрограммирования нет от слова совсем. Вот совсем нет. Даже в C# оно есть в некотором смысле, а в джаве нет совсем вообще никакого. Потому джавушок обычно копипастит код, и течет.

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

              В растговне у нас есть пара макросов. В расте довольно мощная (где-то 60% от сишных шаблонов) макропитушня. Типобезопасная, и на расте, но я ее пока плоховато знаю
              Ответить
    • С днём знаний, питухи!

      Опять в школу ((((((
      Ответить
      • Пишут, в Златохуйске наводнение, дети в школу на надувных лодках добираются.
        Ответить
      • Как защитить и защититься от буллинга в школе
        Ответить
    • chatGPT спешит на помощь

      template <typename OutStream, size_t... I>
      bool send_message_helper(OutStream& _out_stream, const std::vector<auto>& objs, std::index_sequence<I...>) {
          return _out_stream.send_message(objs[i]...);
      }
      
      template <typename OutStream>
      bool send_message_with_objs(OutStream& _out_stream, const std::vector<auto>& objs) {
          switch (objs.size()) {
              case 1:  return send_message_helper(_out_stream, objs, std::index_sequence<0>{});
              case 2:  return send_message_helper(_out_stream, objs, std::index_sequence<0, 1>{});
              case 3:  return send_message_helper(_out_stream, objs, std::index_sequence<0, 1, 2>{});
              // ... continue for other sizes up to 20
              case 20: return send_message_helper(_out_stream, objs, std::index_sequence<0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19>{});
              default:
                  fprintf(stderr, "error: Too much attached objects (%lu), talk to developer\n", objs.size());
                  return false;
          }
      }
      
      auto objs = it.get_objects();
      bool sent = send_message_with_objs(_out_stream, objs);
      
      if (!sent) {
          fprintf(stderr, "error: Unable to send message to output pipe\n");
          return false;
      }
      Ответить
      • херота не лучше, чем у опа
        Ответить
        • почему
          Ответить
          • Та же хуйня с 20 кейсами и перечислением вручную индексов. Просто обмазаная метушнёй.
            Чатжпт опять обосрался.

            Здесь нужно как минимум заменить закат солнца вручную index_sequence на make_index_sequence

            Ещё можно превратить send_message_helper в функциональный объект с шаблонным оператором вызова (можно шаблонизированную лямбду запилить) и в свиче писать только
            case XX: send_message_helper(std::make_index_sequence<XX>{})
            Ответить
            • а зачем вообще эта питушня? Почему не передать указатель на массив и его размер?
              Ответить
              • Да хуй его знает, почему send_message не принимает ссылку на контейнер. Сделать variadic template для произвольного количества аргументов они осилили (они же 20 перегрузок не ручками писали, правда?), а цикл по кртейнеру — нет.
                Ответить
                • Я бы подумал про перформанс, но на самом деле двадцать питухов и так передаются через указатель: они в реестры же не влезут.

                  В дебрях Console.Write в CLR я встречал код где вместо varagrs сделали перегрузку со сторопицот аргументов, но там видимо потому, што вараргс порожет массив в куче. А в крестах-то зачем?
                  Ответить
                • по кротейнеру
                  Ответить
                • Кстати, а make_unique сделан на основе вариадик темлейтов и их фишки в раскрытие в лист инициализации или вызов метода с кучей аргументов?
                  Ответить
    • Почему я не могу полиморфно создать объект на стеке не зная его размера? Потому что размер стека должен быть известен в момент компиляции?
      Что-ж, это логично.

      А как тогда работают VLA и alloca? а? а? а??
      Ответить
      • > я не могу полиморфно создать объект на стеке не зная его размера?

        Можешь. https://govnokod.ru/27525#comment648368
        Хотя смотря что значит "объект"

        > размер стека должен быть известен в момент компиляции?

        Нет.
        Ответить
        • &gt;Нет
          Кажется, до C99 это было так.

          &gt;Хотя смотря что значит "объект"
          Да любая структура, похуй.

          Может быть такая функция, которая возвращает "нечто" плюс размер?
          Ну то-есть сначала идет usize_t, а затем сколько-то байт. Или ABI такого не позволяет?
          Ответить
          • > Может быть такая функция, которая возвращает "нечто" плюс размер?
            > Ну то-есть сначала идет usize_t, а затем сколько-то байт. Или ABI такого не позволяет?

            В сишке и крестоговне этого нет, но вообще сделать что-то подобное на ассемблере можно: https://govnokod.ru/25602#comment477597
            Ответить
      • > Почему я не могу полиморфно создать объект на стеке не зная его размера?
        Потому что кусок стека под возвращаемый объект выделяется до вызова функции, а потом на стек кладётся адрес разврата и аргументы вызываемой функции.
        И да, на ассемблере можно придумать обход этого (например, вызываемая функция создаёт полиморфный объект у себя в стеке, а после возврата её фрейм «склеивается» с фреймом вызывающей функции), но ни сишные, ни крестовые ABI такого не позволяют.
        Ответить
        • Почему нельзя такой ABI сделать чтоб коля сначала сообщил размер возвращаемого значения, колер его выделил, а потом его туда поклал?
          Ответить
          • > сообщил размер возвращаемого значения
            Телепатически?
            Ответить
            • Да нет. Ну вот представим себе такой ABI, в котором сначала в регистр кладется размер значения, затем выделяется место, затем дергается спец инстру...

              ...

              в этом месте я понял, что менять придется не только ABI, но и ISA процессора: исправлять то, как работает CALL
              Ответить
              • Да.

                Но вообще, кстати, нечто подобное используется в «Winapi»: многие функции, возвращающие объекты неопределённого размера, при отсутствии или недостаточном размеры переданного им выходного буфера возвращают специальный код ашипки и размер буфера, который требуется. То есть можно сделать что-то вроде:
                DWORD requestedBufferSize = 0;
                WindoFunkcija(NULL, 0, &requestedBufferSize);  // Получаем размер
                LPVOID buffer = VlaAlloc(requestedBufferSize);  // Выделяем хоть на стеке
                WindoFunkcija(buffer, requestedBufferSize, NULL);  // Получаем результат
                // TODO: обработать случай, когда между вызовами размер объекта изменяется и надо снова доаллоцировать буфер

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

                  Перформанс!!1
                  Ответить
                  • Сходимость у них хорошая. Хотя обычно требуется всего 2 раза звать, но ты можешь опитузировать на пирфоманс, выделив заранее.
                    Ответить

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