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

    +1

    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
    81. 81
    82. 82
    83. 83
    84. 84
    85. 85
    86. 86
    87. 87
    88. 88
    89. 89
    90. 90
    91. 91
    92. 92
    93. 93
    94. 94
    // https://github.com/j123123/sexpr_parse/blob/584fc23de71bebe02545214f819e16b720a2c1e2/my_struct_utils.c#L119
    
    blob *
    blob_scan_fromstream
    (
      FILE *stream
    )
    {
      size_t st_len = 0;
      size_t st_alloc;
      uint8_t *st = NULL;
    
      while(true)
      {
        const int fg = getc(stream);
        if(fg == EOF)
        {
          PRV_ERR_MACRO();
        }
        uint8_t c = fg;
        if(!isprint(fg))
        {
          PRV_ERR_MACRO();
        }
        switch(c)
        {
          case '\\':
            {
              int c2 = getc(stream);
              switch(c2)
              {
                case 'x':
                  {
                    int c3[2] =
                    {
                      getc(stream),
                      getc(stream)
                    };
                    uint8_t tmp[2];
    
                    for(size_t i = 0; i < 2; ++i)
                    {
                      switch(c3[i])
                      {
                        case '0' ... '9':
                          tmp[i] = c3[i]-'0';
                          break;
                        case 'a' ... 'f':
                          tmp[i] = c3[i]+10-'a';
                          break;
                        case 'A' ... 'F':
                          tmp[i] = c3[i]+10-'A';
                          break;
                        default:
                          PRV_ERR_MACRO();
                      }
                    }
                    M_PUSH(tmp[1] | tmp[0] << 4);
                  }
                  break;
                case '\\':
                  M_PUSH('\\');
                  break;
                case 't':
                  M_PUSH('\t');
                  break;
                case 'n':
                  M_PUSH('\n');
                  break;
                case '"':
                  M_PUSH('"');
                  break;
                default:
                  PRV_ERR_MACRO();
              }
            }
            break;
    //      case '\t':
    //      case '\n':
    //        PRV_ERR_MACRO();
    //        break;
          case '"':
            goto end;
          default:
            M_PUSH(c);
        }
      }
    
    end:
      ;
      blob *tmp = blob_init(st_len, st);
      PRV_FREE(st);
      return tmp;
    }

    Эта вот хрень вычитывает из "FILE *" одно "слово".

    Запостил: j123123, 09 Ноября 2021

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

    • см. https://govnokod.ru/27679#comment674971
      https://govnokod.ru/27679#comment710504

      Это конечно так делать не надо, хуета какая-то. Надо чтоб "генератор лексических анализаторов"
      Ответить
      • > генератор

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

          inerator g(n: int): int =
              var k: int = 0
              while (k < n):
                  yeild k
                  inc k
          Ответить
          • Тут не такие генераторы имелись в виду...
            Ответить
            • > генераторы

              def a():
                  for n in range(10):
                      yeild n
              
              def b():
                  while(True):
                      yeild 0
              Ответить
            • Спутать генераторы парсеров и лексеров и ленивые итераторы это пять.

              Вспоминается история Икануса про двух людей, спорящих про DN.
              Один говорил про Duke Nukem, а другой про Dos Navigator
              Ответить
              • > генераторы
                def generate_random():
                    import random
                    return random.randrange(100)
                Ответить
              • > итераторы

                parser = Lark('''?sum: product
                                     | sum "+" product   -> add
                                     | sum "-" product   -> sub
                                 ?product: item
                                     | product "*" item  -> mul
                                     | product "/" item  -> div
                                 ?item: NUMBER           -> number
                                      | "-" item         -> neg
                                      | "(" sum ")"
                                 %import common.NUMBER
                                 %import common.WS
                                 %ignore WS
                         ''', start='sum')
                Ответить
              • Как будто есть какая-то разница.
                Ответить
        • генераторы гавно.. все нормальные генераторы пишут ручками (по схеме но ручками). я как не опытный пытался писать на (каком то генераторе) в конечном итоге это говно парсило пол дня простой текст
          Ответить
          • > генераторы

            int g() 
            {
                for (i = 0; i < 10; i++) {
                    sleep(100)
                    return i
                }
            }
            Ответить
          • > парсило полдня

            Ну... видимо ты какую-то недетерминированную грамматику туда захуярил и бедный парсер её перебором с откатами потом разбирал?

            Я не вижу других причин.
            Ответить
            • Парсер разве не должен быть детерменированным?
              Ответить
              • Документ в целом должен однозначно парситься, а вот где-то в середине парсинга может быть неоднозначность.

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

                Не помню уже названия для этих классов грамматик
                Ответить
                • > Тот же бизон умеет и вперед немножко подглядывать для разрешения конфликта и форкать стейт в неоднозначных точках и смотреть какой выживет.

                  Это как в крестоговне с "жизнеспособностью" при вызове правильной функции https://govnokod.ru/27443#comment630395 ?
                  Можно считать баллы у двух или более стейтов по каким-то критерям, и выживает вореант, набравший максимум баллов.

                  А если сделать хуйню, где правила определения коэффициента жизнеспособности вореанта парсинга хуйни можно будет описывать на тьюринг-полном языке в виде специальной аннотации, парсинг может никогда не завершиться
                  Ответить
                  • Желательно чтобы эти правила можно было писать в самом разбираемом тексте. Причём в любом месте, даже в конце, чтобы парсить было интереснее. И влиять они должны даже на парсинг самих себя.
                    Ответить
                  • Можно описать в аннотациях к фразе "сделать заебись" какую-то формальную спецификацию. И парсер должен будет так разобрать эту фразу, чтобы получился код, удовлетворяющий спеке.
                    Ответить
    • Какой конченный автомат )))

      Кому нужны генераторы, если есть десяток трудолюбивых олимпиадников?
      Ответить
    • > case '0' ... '9':

      Ого, не знал, что так можно.
      Ответить
      • Это гццизм.
        Ответить
        • Скажи вот мне, как рубящий в ремонте человек. Если стояк батареи это общедомовое имущество, а отводка от него (включая кран) имущество мое, и УК забыла поставить перемычку, так что когда я выключаю батарею -- я блокирую стояк, и соседи бузят, я могу же их посылать в УК? Кран -- моя собствненость, и я не обязан его открывать, верно?
          Ответить
          • Тут скорее и батарея и кран -- имущество УК т.к. они не отделены от стояка и являются его частью...

            Вряд ли без перемычки возможно это разделение ответственности.

            > посылать в УК

            Чтобы они потом засудили тебя нахуй за то что дом оставил без отопления? )))

            Лучше позвони им и попроси байпасс приделать как положено.
            Ответить
            • Кран имущество УК, но ставил я его за свой счет, и если он протечет -- меня выебут соседи

              Охуенно же

              Ну вообще я имел ввиду, что они должны поставить байпасс, а не требовать от меня "открыть кран"
              Ответить
              • > а не требовать

                У юристов не бывает транзитивности, емнип.

                Нельзя взять и сократить "сварщик не доделал работу и мне жарко" + "я закрыл кран и оставил соседей без тепла" до "сварщик не доделал работу и оставил соседей без тепла".
                Ответить
                • А причем тут сокращение?

                  Есть же какие-то законы, говорящие что я могу и не могу делать.

                  Я не могу портить общедомовое имущество
                  Я могу делать что угодно со своим имуществом
                  Кран -- мое имущество

                  Если электрик сойдет с ума, и заземление из моей квартиры с этажа проведет к батарее соседки, и ее ебнет, буду ли я виноват в том, что включил в розетку стиралку с металлическим корпусом?
                  Ответить
                  • > если её ебнет

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

                    Но вот если ты знал о проблеме и умышленно не открываешь кран или продолжаешь юзать эту машинку несмотря на просьбы соседей -- то ты пидор и будешь за это отвечать. Как и накосячивший электрик/сантехник.
                    Ответить
                  • > своим имуществом

                    Ну как сказать... вроде бы по закону ты не можешь приварить радиатор слишком большой площади, т.к. это создаст дизбаланс соседям. Скорее всего блокировка потока в те же нормы прописана.
                    Ответить
                    • У радиаторов есть мощность. В ваттах. Есть нормы по количеству необходимого тепла. В килокалориях в час. Считается для каждого здания по своему. Если одно сильно превышает другое, другим будет холодно, и когда пидара вычислят, ему пересчитают коммуналку на фактически потреблённое тепло.
                      Ответить
                  • Даже опуская вопрос, кому принадлежит кран, всю ответственность за его использование будешь нести ты.

                    Весь стояк остался без тепла? УК придётся вернуть деньги за некачественно оказанную услугу → УК стребует эти деньги с тебя. Если УК оштрафуют, они и сумму штрафа с тебя могут истребовать. Из-за резко закрытого крана выбило стык на чердаке и 10 квартир оказались залиты кипятком? Плати. Да, он был проржавевшим насквозь, но «система успешно прошла испытания перед началом отопительного сезона, экспертиза установила причиной неквалифицированные действия guest6, спровоцировавшие гидроудар, поднявший давление в отдельных участках отопительной системы намного выше нормальных эксплуатационных величин». Чей-то попугайчик замёрз? Надеюсь, он не был очень дорогим.
                    Ответить
                    • Ко мне в квартиру за 3 года никто не заходил и не проверял ни газовые трубы, ни отопление.

                      // я другой гость
                      Ответить
                  • > я могу делать что угодно со своим имуществом

                    Нет. См. пример про телек ночью.
                    Ответить
          • > не обязан его открывать

            З.Ы. Я помню у нас в доме тоже как-то завёлся пидор с последовательно подключенным краном, которому было жарко зимой... Всем стояком его искали чтобы выебать.
            Ответить
            • Ну как, нашли и выебали?
              Ответить
              • отняшили
                Ответить
              • Нашли. Он оказывается вообще не понимал, что весь стояк блочит своим краном... Приварили байпасс в итоге.
                Ответить
                • Ну то есть это в итоге была вина УК, что байпас не поставили? Он же ничего не платил, и его не заставили включать батареи?
                  Ответить
                  • Заставили включить конечно до установки перемычки.

                    Ситуация ничем не отличается от тех, у кого кранов вообще нет.
                    Ответить
                    • УК в итоге за свой счет поставили перемычку?
                      Ответить
                      • Ну да, их мудило же варило кран и забыло перемычку приварить.
                        Ответить
            • Только
              > со стояком его искали, чтобы выебать
              Ответить
              • Это про десктопа, у него тут у единственного ещё бывает стояк, поэтому он нам, половым дисфункционерам, иногда кажется пошлым.
                Ответить
            • То есть человек не имеет права выключить батарею зимой если ему жарко?
              пиздекц
              Ответить
              • Человек не имеет право выключить батарею тем, кто этого не желает. Себе — пожалуйста.
                Ответить
                • Я отключил свою батарею используя свой кран

                  Почему при этом отключилисб батареи у соседей я не знаю
                  Вероятно, УК что-то криво провел
                  Разве это моя вина?
                  Это вина УК

                  А свет я могу себе выключить? Вдруг он тоже соседям холодильник отключит?
                  Ответить
                  • Вина УК в том что они забыли перемычку и тебе жарко. Твоя вина в том, что остальным холодно.
                    Ответить
                  • Используй "перемычку" (она же "байпас")
                    https://aqua-rmnt.com/interesnoe/zachem-nuzhna-peremychka-na-bataree-otopleniya.html
                    Ответить
                    • ее и нужно ставить
                      вопрос в том, кто это должен делать
                      Ответить
                      • Ну тут джва отдельных дела:

                        - Ты оставил соседей без тепла, поэтому ты обязан открыть кран.
                        - Мудак, варивший трубы, не доделал работу, поэтому он должен её закончить. Бесплатно.

                        Ну собственно если он из УК, туда и обратись.
                        Ответить
                        • >обязан открыть кран

                          Вот этот момент мне непонятен. Кран мое имущество, стояк общедомовое.
                          Общедомовое я не имею права трогать, а кран имею: я его ставил за свои деньги, я за него отвечаю, если он протечет -- то я буду платить денег.

                          По-моему соседи должны выебать УК, и УК должны послать мне сантхника, которому я обязан предоставить доступ к стояку (как к общедомовому имуществу) и он должен поставить туда байпасс
                          Ответить
                          • И пока он будет ставить байпасс, куча народу должно без тепла сидеть?

                            Какой эгоизм ))))

                            Не, ну если они согласны -- я думаю никто и не заставит открывать кран. Но они УЖЕ пожаловались, раз управляшка к тебе пришла.
                            Ответить
                            • Ко мне еще не пришла управляйка, ко мне соседка приходила.

                              Я не против открыть кран на время пока они ставят байпасс, но мне совершенно не понятно почему я обязан постоянно сидеть с этим краном, если это косяк управляйки?

                              У меня просто горит жопа от того, что если кран протекает, то это ТВОЙ кран и ты должен нижним соседям полтора ляма

                              Если ты хочешь его поменять, то это ТВОЙ кран и ты платишь сантехнику за его замену

                              А если ты хочешь его закрыть, то сразу это общий кран, и делать этого нельзя.

                              Хуйня же, ну?
                              Ответить
                              • Ну вот у тебя есть свой телек, но ты не можешь включить его на всю громкость ночью.

                                Хотя казалось бы -- это твой телек в твоей хате.
                                Ответить
                    • Какой шунт )))
                      Ответить
                  • Я отключил себе воду используя кран в подвале. Как что провели строители я не ебу вообще. ХЗ, отключилось что-то у кого-то ещё.
                    Разве это моя вина?
                    Ответить
                    • У меня нет доступа в подвал, и подвал это не мое имущество
                      А кран мое

                      Я просто хуею с того, что если кран потечет то я буду его менять за свой счет
                      но закрыть не могу
                      Ответить
                      • Крутить протекающий кран в системе, находящейся под давлением -- не самая лучшая идея, как мне кажется...
                        Ответить
                        • Эээ? Нельзя закрыть кран на батарее? Нахуй он нужен тогджа?
                          Ответить
                      • > за свой счёт

                        Ну почему... в теории ты можешь его поменять за счёт завода, который делал кран или сварщика если они обещали, что всё будет заебись N лет.
                        Ответить
                        • Гарантия на установку батареи три года, увы.
                          но это мои отношения с тем, кто его ставил

                          Важно, что управляйка его не ставила в данном случае
                          Ответить
                          • Ну вот кто ставил -- тот и будет варить байпасс за свой счёт. А то понаварят хуйни в общий стояк.
                            Ответить
                          • > управляйка его не ставила

                            Так всё-таки кто кран то поставил?

                            Рукожоп из управляйки или рукожоп которого ты сам нанял?


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

                            Во втором случае они придут, откроют кран и ты будешь сам разбираться с рукожопом и/или варить за свой счёт.
                            Ответить
                  • разбирайся/судись с УК, нафига ты соседям под коврик срёшь?
                    Ответить
              • То есть человек не имеет права сливать унитаз на соседей снизу если сантехник забыл подключить его к трубе?

                Как страшно жить в этом мире...
                Ответить
                • Лить гамно — не право, а привилегия.
                  Ответить
                • >То есть человек не имеет права сливать унитаз на соседей снизу если сантехник забыл подключить его к трубе?


                  Совершенно верно.

                  Если управляющая компания не заделала дырку в фановой трубе (в смысле в стояке между этажами), то она ее должна заделать.

                  Она не имеет права сказать "не срите пожалуйста, потому что иначе соседей зальет"
                  Ответить
      • Так можно в руби, перле (там правда в классическом варианте свича нету), и кажется в паскале
        Странно, что так можно в C

        А вон там снизу подсказывают, что это в GCC можно
        Ответить
    • https://github.com/j123123/sexpr_parse/blob/584fc23de71bebe02545214f819e16b720a2c1e2/my_struct.c#L182
      можно подумать, что тут какая-то хуйня
      // нахуя мне тут "CHAR_BIT*sizeof(unsigned long long)" ?
        const size_t bytes_allocated =
          1ULL <<
          (
            CHAR_BIT*sizeof(unsigned long long)-
            __builtin_clzll(sizeof(stack)+len*sizeof(node_elm))
          );

      _builtin_clzll() должна посчитать лидирующие нулевые биты в числе(для типа unsigned long long - см. https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html ), а мне тут нужно получить позицию последнего единичного бита, если считать от младшего к старшему. Например, если есть число, которое в двоичном представлении имеет вид
      0b00001011
      то мне надо вернуть 4 т.к. в четвертой позиции этот бит находится
      0b00001011
            4321 // да, тут нумерация не с нуля, а с единицы

      И тут поэтому будет выделено памяти в худшем случае в 2 раза больше, а в лучшем случае на 1 бит больше, чем надо. https://wandbox.org/permlink/Plw7PlVbQ7hGajFd

      Структура stack:
      // https://github.com/j123123/sexpr_parse/blob/584fc23de71bebe02545214f819e16b720a2c1e2/my_struct.h#L61
      
      struct stack
      {
        stack_sz len;
        size_t sz_bytes;
        node_elm nodes[];
      };

      Этот nodes[] - flexible array member, чтобы не указатель на хуйню хранить, а просто сзади структуры. https://port70.net/~nsz/c/c99/n1256.html#6.7.2.1p16
      Ответить
      • Кстати, а что там в std::vector, там размер хуйни и сами данные хранятся одним куском, как в этом примере с "flexible array member" или там типа структура, в которой количество элементов и потом указатель на хуйню с этими самыми элементами?
        Я вот попробовал посмотреть в libstdc++ из GCC, там какая-то ебаная непонятная хуйня написана.
        https://github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/include/bits/stl_vector.h

        Но непохоже, чтобы оно в эту "struct _Vector_base" что-то непосредственно встраивало
        Ответить
        • Три поинтера вроде в самом векторе, а данные в куче. Ну или поинтер и джва размера.

          А оптимизация для мелочи с хранением прям в самом векторе не везде есть.
          Ответить
          • А какие есть причины хранить размер вектора не в том же самом куске памяти, где и сам вектор?

            Почему реализация STL из GCC такое ебаное говно с кучей "#if" и "#ifdef" и всяким макроговном? Это принципиально нельзя написать нормальным образом?
            Ответить
            • > не в том же куске памяти

              А нафиг за ней так далеко лазить?
              Ответить
              • В смысле?
                Ну вот например можно хранить вектор как
                template <typename T> 
                struct array { 
                  size_t sz;
                  T *array_ptr; 
                };

                или
                template <typename T> 
                struct array { 
                  size_t sz;
                  T array_data[]; // flexible array member
                // данные рядом с самим размером, не нужно лишних разыменований
                };

                Чем второй вариант хуже чем первый?
                Ответить
                • Оффсетом до данных.
                  Ответить
                  • Оффсет относительно начала структуры (т.е. адрес, где начинаются непосредственно данніе) там известен на этапе компиляции, так что он не влияет. А вот лишнее разыменования влиять может.
                    Ответить
                    • Разыменование у тебя хоть как есть, если твой array не фиксированной длины на стеке.

                      И вот как раз во втором варианте до длины лишнее разыменование.
                      Ответить
                      • Ну допустим я куда-то передаю указатель на первую структуру (где T *array_ptr;) - чтобы добраться до самих данных, мне надо из самой структуры достать указатель arr_ptr и потом его разыменовывать уже.
                        А если я передаю указатель на вторую структуру (где T array_data[]; // flexible array member ) то надо лишь добавить к указателю на такую структуру размер size_t, и вот уже можно читать данные
                        Ответить
                        • Это нечестное сравнение. Первую структуру ты передаешь по указателю чтобы её можно было ресайзить и т.п. Для r/o её и по значению можно передать. Ну и встраивается она напрямую.

                          Вторая структура по одному указателю r/o. Для ресайза надо двойную индирекцию. И встраивается только по указателю.
                          Ответить
                          • Да, чтобы вторую ресайзить, нужен указатель на указатель на такую структуру. Или возвращать новый указатель после ресайза через return как вариант.

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

                            Ну хорошо, а допустим если мне нужны константные (т.е. неизменяемые в рантайме) строки из байт, как более адекватная замена нуль-терминированным говнострокам сишки, но чтобы без Шлемазла Шлемиэля т.е. чтоб не нужно было прочитывать строку до конца для узнавания размера строки? И для такой хуйни понаделать структурок
                            Можно например сделать варианты
                            struct array_8 { 
                              uint8_t sz;
                              uint8_t array_data[];
                            };
                            
                            struct array_16 { 
                              uint16_t sz;
                              uint8_t array_data[];
                            };
                            
                            struct array_32 { 
                              uint32_t sz;
                              uint8_t array_data[];
                            };
                            
                            ...

                            И для такой хуеты понаделать аналог strdup, типа функций вида datadup8() datadup16() datadup32(), отдельно для конкатенаций надо перебирать еще разные варианты datacat8_8() datacat8_16() datacat8_32() datacat16_8() ... и тут еще нужно как-то указывать, в какую строку оно должно попытаться сконкатенировать
                            Ну типа если надо из двух array_8 слепить array_16 то будет так
                            void datacat8_8_16(struct array8 *src1, struct array8 *src2, struct array8 *dst)

                            и это еще можно в макросню типа _Generic завернуть, чтобы удобно было
                            Ответить
                            • Какая история одного байта )))

                              Надеюсь вся эта кобенаторика не сожрёт профит от компактных строк.
                              Ответить
                              • Для контроллеров можно оставить только те функции, которые реально нужны. Если массивов размером до 256 байт хватит на всё, оставить только datadup8() и datacat8_8_8(). Ну и сделать еще макросов DATADUP8_ALLOCA() и DATACAT8_8_8_ALLOCA() которые б разворачивались в хрень с alloca для выделения на стеке, чтобы хип не использовался
                                Ответить
                                • Можно старший бит 8-битной формы пожертвовать на выбор формы. Ну и пару старших у 16-битной. Тогда datacat и datadup смогут все размеры автодетектить.
                                  Ответить
                                  • >Можно старший бит 8-битной формы пожертвовать на выбор формы

                                    какой утф ))
                                    Ответить
                            • А зачем тебе три вида оверинжиринга? Надо признать один основным и ветвить маркосами.
                              Ответить
                              • Средний 16-битный вариант сомнителен, да.

                                У 32-битки оверхед при n>=256 в районе процента. А меньшие покрывает компактная 8-битка.
                                Ответить
                        • Первая форма еще в регистрах может лежать. А вторая нет.
                          Ответить
                        • > размер size_t

                          max(alignof(T), sizeof(size_t)), но не суть. Подумаешь немного байтов проебали в начале вектора. Некритично.

                          Да и size_t обычно и так один из самых жирных типов. Больше только аппаратные вектора.
                          Ответить
                    • Ну или вот посмотри на двоичный поиск.

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

                      Со второй структурой ты вынужден загрузить лишний кешлайн в котором лежит размер. А этот кешлайн в большинстве случаев не пригодится при поиске.
                      Ответить
                • Кста, в Qt насколько помню именно второй вариант юзают чтобы корова работала.
                  Ответить
                  • Да, в Qt QString -- это просто указатель на блок, в котором лежит счётчик ссылок, длина строки, длина буфера, какие-то флаги и сам буфер (ushort array[1]).

                    А в libstdc++ три поинтера: начало, конец строки и конец буфера.
                    Ответить
                • шото я не понял вас: Вектор же свой размер и указатель на данные хранит на стеке (ну или куда ты там его положишь), в общем содержит их внутри себя

                  А сами данные могут быть где угодно, это как аллокатор решит, могут быть и в куче
                  Ответить
            • Кстати, если бы все буфера передавались рейнджами, то не надо было бы тратить место в куче на хедера аллокатора. Было бы что-то в духе
              range r = malloc(80);
              range s = gets(r);
              while (s.begin < s.end) {
                  range t = strtok(&s, " ");
                  puts(t);
              }
              free(r);
              Красиво же.
              Ответить
              • > gets(r);

                Какая секурность )))
                Ответить
                • Ну вот этот gets не переполняется, кстати. Он же диапазон получает а не указатель. Ну и возвращает заполненный им кусок для обработки. И не надо никаких ноликов и прочей срани в конце. А strtok данные не портит, просто двигает рейндж дальше и возвращает рейндж на откушенный токен.

                  В асме это тоже должно неплохо смотреться.
                  Ответить
              • strkok
                Ответить
              • explode(" ", fgets(STDIN))
                Ответить
                • Ну это уже кучу аллоцирует. Хотя эксплод тоже эффективный будкт в таком представлении.
                  Ответить

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