Кресты / Говнокод #28841 Ссылка на оригинал

0

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  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_ YpaHeLI_, (Updated )

Комментарии (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
      Хотя смотря что значит "объект"

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

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

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

        Может быть такая функция, которая возвращает "нечто" плюс размер?
        Ну то-есть сначала идет 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 раза звать, но ты можешь опитузировать на пирфоманс, выделив заранее.
                  Ответить

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

Где здесь C++, guest?!

    А не использовать ли нам bbcode?


    8