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

    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
    #include <stddef.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    void *govno[300] = {NULL};
    
    size_t govnopoindex = 0;
    
    void chisti_govno(void)
    {
      do
      {
        free(govno[--govnopoindex]);
      } while (govnopoindex != 0);
    }
    
    
    char *concat(char *a, char *b)
    {
      char *ptr = malloc(strlen(a)+strlen(b)+4);
      if (ptr == NULL)
      {
        fprintf(stderr, "Huli ty obosralsya, mudak blyad? Ves' heap zasral\n");
        chisti_govno(); // иди под струю мойся
        exit(-1);
      }
      sprintf(ptr, "(%s*%s)", a, b);
      govno[govnopoindex++] = ptr;
      return ptr;
    }
    
    
    char *pow_gen(size_t n, char *a, char *p)
    {
      if (n == 0)
      {
        return a;
      }
      if (n & 1)
      {
        return pow_gen(n >> 1, concat(a, p), concat(p, p));
      }
      else
      {
        return pow_gen(n >> 1, a, concat(p, p));
      }
    }
    
    char* pow_b2(size_t n) {
      return pow_gen(n, "1", "a");
    }
    
    void printfshit(const size_t pow)
    {
      printf("double pow_%zu(double a) {return %s;}\n\n", pow, pow_b2(pow));
    }
    
    
    int main(void)
    {
      printfshit(255);
      chisti_govno();
      return 0;
    }

    http://govnokod.ru/23246#comment388959 - считаю что это заслуживает отдельного говнокода

    Запостил: j123123, 10 Августа 2017

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

    • Оригинальная шаблонная метушня, написанная бормандом
      template <size_t N>
      double pow_b2_impl(double a, double p) {
          if (N == 0) {
              return a;
          }
          if (N & 1) {
              return pow_b2_impl<(N>>1)>(a*p, p*p);
          } else {
              return pow_b2_impl<(N>>1)>(a, p*p);
          }
      }
      
      template <size_t N>
      double pow_b2(double a) {
          return pow_b2_impl<N>(1, a);
      }

      Портировалось довольно легко.

      Скажите, а в плюсовых шаблонах только через хвостовую рекурсию можно долбиться, циклов не завезли?
      Ответить
      • есть еще вариант делать через integer_sequence, как делал я. А полноценного for constexpr к сожалению не завезли, хотя над этим работает тот же Саттер
        Ответить
        • Реализация integer_sequence в плюсах выглядит как говно http://govnokod.ru/23263
          Ответить
      • > Портировалось довольно легко.
        А если добавить к шаблону параметр T вместо double, то и портировать ничего не надо. Достаточно подсунуть структуру с operator* который делает concat.
        Ответить
        • > Достаточно подсунуть структуру с operator* который делает concat.

          Это потому что быстрое возведение в степень работает для любого моноида.
          Ответить
        • > А если добавить к шаблону параметр T вместо double, то и портировать ничего не надо.

          Кстати, да. Говно с шаблонами еще и в том, что в качестве шаблонного параметра нельзя передавать плавучего питуха.
          Ответить
          • > в качестве шаблонного параметра нельзя передавать плавучего питуха
            Побоялись специализации шаблонов по плавучке, походу.
            Ответить
            • Решили спасти мир от восстания машин. Из-за машинного эпсилон и всего такого плавучие питухи труднее воспроизводятся, чем целые (если только не собирать их по битам вручную), поэтому, например, рекурсивный шаблон с плавучим параметром может выдавать непредсказуемые результаты (самое безобидное — зацикливание на этапе компиляции).
              Ответить
    • Тут кстати баг был. Починил, проверь:
      void chisti_govno(void)
      {
        while (govnopoindex != 0)
        {
          free(govno[--govnopoindex]); // чисти-чисти
        }
      }
      
      char *concat(char *a, char *b)
      {
        char *ptr = malloc(strlen(a)+strlen(b)+4);
        if (ptr == NULL || govnopoindex == 300)
        {
          fprintf(stderr, "Huli ty obosralsya, mudak blyad? Ves' heap zasral\n");
          chisti_govno(); // иди под струю мойся
          exit(-1);
        }
        sprintf(ptr, "(%s*%s)", a, b);
        govno[govnopoindex++] = ptr;
        return ptr;
      }


      И вообще, в кодогенератор надо бы запилить мемоизацию какую-нибудь, и стековый аллокатор поверх одного malloc и потом дергать realloc() и расширять, и чтоб потом одним free() его чистить, но мне пофиг.

      А в плюсовых компилтайм-шаблонах кстати есть GC? В компилятор встроили сборщик мусора для шаблонной метушни?
      Ответить
      • > есть GC
        Там следуют заветам PHP: "вот конпеляция закончится - освобожу всю память за раз".
        Ответить
        • В PHP теперь есть GC:
          http://php.net/manual/ru/function.gc-enable.php

          Только никто не проверял, работает ли она реально. Всё равно же процесс сдохнет после завершения обработки запроса (PHP в режиме демона почти никто не использует).
          Ответить
          • Лолшто? Охуеть вообще.
            Ответить
            • Удивило наличие GC в PHP или то, что процесс дохнет? Если второе, то ладно, в режиме FastCGI процесс не дохнет, дохнет контекст (что почти то же самое). А если первое, то где-то даже видел рекомендацию более не используемым переменным присваивать null (или выполнять unset), чтобы их потом собрал GC.
              Ответить
              • >то где-то даже видел рекомендацию более не используемым переменным присваивать null (или выполнять unset), чтобы их потом собрал GC.

                Если надо каким-то образом явно отмечать более не используемые переменные, то зачем тогда GC? Можно с тем же успехом руками мусор собирать через что-то вроде free()
                Ответить
                • Ну в джаве тоже GC не съест объект, если его держит глобалка.
                  Ответить
                • Я понял, что неточно выразился, спутав переменную и объект.

                  Правильно будет так: если объект больше не нужен, то переменной, которая его держит, нужно присвоить новое значение, например, null (или вызвать unset).

                  Хотя это не всегда требуется: если объект держит локальная переменная функции, то она исчезнет после выхода из функции. Обнулять переменную есть смысл только в том случае, если хочется собрать мусор чуть пораньше, чем функция завершится.
                  Ответить
                  • >Правильно будет так: если объект больше не нужен, то переменной, которая его держит, нужно присвоить новое значение, например, null (или вызвать unset).

                    Но ведь по своей сути это является тем же говном, что и говноплюсовый std::shared_ptr

                    http://ru.cppreference.com/w/cpp/memory/shared_ptr :
                    > std::shared_ptr – умный указатель, с разделяемым владением объектом через его указатель. Несколько указателей shared_ptr могут владеть одним и тем же объектом; объект будет уничтожен, когда последний shared_ptr, указывающий на него, будет уничтожен или сброшен.

                    И, как вы понимаете, само по себе это не является GC. Та же Java при сборке мусора поступает значительно умнее, там есть механизмы обнаружения циклических ссылок

                    Хотя вот в PHP такое тоже есть http://php.net/manual/ru/features.gc.collecting-cycles.php

                    Но, как представитель старой школы, я считаю что все это является полным говном, замедляющим выполнение вашей компьютерной программы, к тому же это мешает реалтаймовости (для пхп очень актуально).
                    Ответить
                    • Отдельно бы хотелось отметить говноуёбищность такой хуиты, как std::shared_ptr

                      Вот представьте, вы там выделили где-то память и создаете на нее некоторое количество особых указателей, и когда все указатели будут сброшены в ноль, то тогда эта память освободится. Вроде бы отличная идея, не правда ли? Ан нет, идея-то говно! Это может иметь какой-то смысл только лишь в том редком случае, когда вы не знаете(и не можете никак отследить) на этапе компиляции, какие указатели указывает на этот самый выделенный кусок памяти в конкретный момент времени, и когда(при каких обстоятельствах) этот кусок памяти будет попросту не нужен, и указатели более не используются. Если вы можете точно выделить момент времени в своей компьютерной программе, когда гарантированно ни один указатель не будет указывать на некоторый регион памяти, так тогда вот втулите туда этот самый free(). А это смрад-поинтерное говно под названием std::shared_ptr создано явно для каких-то заедушных анскиллябр, не могущих точно определить время жизни объекта, не втуливая в рантайм какие-то говнокостыли с говноподсчетом ссылкок
                      Ответить
                      • Все америку открываешь? Никто (кроме анскилябр заедушных) шаредпойнтеры просто так и не использует, а только в случаях, когда "вы не знаете(и не можете никак отследить) на этапе компиляции, какие указатели указывает на этот самый выделенный кусок памяти в конкретный момент времени, и когда(при каких обстоятельствах) этот кусок памяти будет попросту не нужен". С асинхронщиной есть такая проблема, например, что контекст должен жить, пока выполняется хоть одна асинхронная операция, связанная с ним.
                        Ответить
                      • > создано явно для каких-то заедушных анскиллябр

                        Оторвись уже от своего восьмибитного говна и осознай, что есть процессоры с более чем одним ядром.

                        shared_ptr нужен редко, но без него было бы грустно. К примеру, он очень кошерен, когда нужно заспаунить N тредов, которые читают один read-only кусок данных, причём у них есть таймаут, в течение которого мы ждём от них ответа, и последний должен за всеми почистить.
                        Или когда пишешь асинхронную лапшу на бустасио.

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

                        > И, как вы понимаете, само по себе это не является GC.

                        Никто и не говорит, что это GC, откуда ты это взял? GC полезен не столько для сбора циклов (эту проблему можно самому решить, если продумать жизненный цикл), сколько для компактификации кучи.
                        Ответить
                        • Таки основная фича гц по сравнению с плюсовым RAII - это защита от висячих ссылок, а не компактификация кучи (в го например нет вроде?).
                          Ответить
                          • > Таки основная фича гц по сравнению с плюсовым RAII - это защита от висячих ссылок

                            "основная" фича или "не основная" — это дело вкуса.

                            Висячие ссылки — это по сути баги, если их нет, то и ГЦ становится "не нужен". Конечно, в асинхронной лапше довольно сложно всё аккуратно сделать, но вполне реализуемо (хоть ГЦ и немного удобнее).

                            А вот компактификацию самому сложно сделать. Фрагментация может быть высокой даже в "корректных" программах. Можно, конечно, писать царские слаб-аллокаторы или жонглировать аренами, но если можно позволить себе жить с ГЦ, то почему бы и нет.
                            Ответить
                            • Зачем нужна компактификация? Особенно рядовому пользователю языков с гц?
                              Ответить
                              • > Особенно рядовому пользователю языков с гц?
                                Почти у всех рядовых пользователей GC она и так есть.

                                Если пишешь нагруженный сервер на плюсцах, то одно неверное движение (какой-нибудь lexical_cast<int> в цикле [1]) может заставить его подтекать на гигабайт в день, в итоге он будет временами крэшиться, жрать цпу и мешать спокойно спать по ночам.
                                Поэтому люди, которые пишут нагруженные программы с кучей аллокаций (редисы, файрфоксы, фейсбуки, гуглы), так любят jemalloc — там довольно много усилий приложили, чтобы избегать фрагментации.

                                [1] https://www.facebook.com/notes/facebook-engineering/chat-stability-and-scalability/51412338919/
                                Ответить
                        • > Или когда пишешь асинхронную лапшу на бустасио.
                          Причем, любое, даже старое сраное приложение не одноразового однозадачного запуска - это ивент луп в бесконечном цикле. Практически любая ембедщина - это сука 100% ивент луп, т.к. ему надо работать 24/7.
                          Асио и есть ивент луп, только в правильной, современной форме (господи, ему уже за 10 лет, пиздец какой современный). Где не имеется ровно 1 основной тред на обработку всех сраных событий, хранящихся в глобальных переменных (держу пари, я прямо в точку попал, да, j123123?), и когда все прочие задачи виснут к хуям, пока текущая подпрограмма не закончит свою работу и не попустит поток исполнения.

                          Я знаю почему пригорает у неосилятора.
                          Просто есть вычислительные платформы, где есть инструменты и возможности (компиляторы и ядра), а есть дерьмо 20 летней давности, где только на сишке, работающей в одно щячло, и можно писать.
                          Ответить
                          • > Где не имеется ровно 1 основной тред на обработку всех сраных событий
                            Почти никогда не использую ио_сервис в многопоточном режиме (только если вместо тредпула). И все примеры, что видел - забагованная лапша из страндов. Наблюдал несколько случаев, как люди переходят к модели один ио_сервис - один поток.
                            Ответить
                            • Это пиздец. Ну могу посоветовать иногда проектировать, а потом уже писать софт.
                              Ибо мне нечего возразить, кроме "наверное, попробуйте ещё раз".
                              Стоит начать с квадратиков, из которых стрелочки идут в другие квадратики, инфа 100%.
                              Ладно, это было невежливо.

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

                                > Странды - грубо, точки скрещивания нескольких потоков.
                                Странд - это асиошный способ сделать поток выполнения. Самый хуевый из возможных, т.к. допускает миллион способов отстрелить себе ногу. Неудачный костыль, не более.
                                Ответить
                                • Любой пример, где у тебя есть высокая конкурентность однотипных задач. Например, веб/сетевой-сервер. Из жизни - в свое время пришлось сделать собственный брокер риалтайм событий, который работает по вебсокету с клиентами (подписка/мультикасты и т.д.). Одна из инсталляций этого сервера сейчас обслуживает 10к онлайн клиентов и не напрягается, футпринт там около 50-100МБ памяти и 0% загрузки ЦПУ (посчитайте на досуге, сколько сожрёт жабонька с теми же параметрами). Число потоков в пуле настраивается, насколько я помню, 100 потоков для 10к в самый раз.

                                  Но классические примеры не мешают делать нормальные универсальные приложения на тех же принципах - единый иосервис, единый пул тредов (например, 10), все порождаемые задачи (разные по сути) работают в указанном пуле. Вообще крайне здраво проектировать и писать софт так, чтобы он не рожал кучу потоков, не занимающихся ничем, а исполняющейся задаче было поебать работает она в пуле из 1 треда или из 100. Это, как сказать, хорошо влияет на масштабируемость и ресурсопотребление.

                                  Странд - очередь задач исполнения, есть быть точным. Ты можешь пользоваться этой вещью только тогда, когда ты действительно хочешь получить гарантию непараллельного выполнения двух порождённых тобой подзадач, и не пользоваться всё остальное время. Вместо этого "неудачного костыля" ты мог бы писать царские блокировки, заставляя параллельный поток простаивать, или пессимизировать в однопоточный ио-сервис (потому что так проще и не надо включать голову).
                                  Ответить
                                  • > Любой пример, где у тебя есть высокая конкурентность однотипных задач.
                                    Как раз в этом случае нет никаких причин городить общую очередь задач на несколько потоков, а можно раскидывать задачи по нескольким иосервисам.

                                    > 100 потоков для 10к в самый раз.
                                    Ну а у меня демон с 50 потоками держит полмиллиона соединений. Иосервис на поток - пирфомансней.

                                    > делать нормальные универсальные приложения на тех же принципах - единый иосервис, единый пул тредов
                                    И ебаться с датарейсами из-за забытого странд.врап.

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

                                      энивей, мы уклонились от темы shared_ptr для питухов
                                      Ответить
                          • >и когда все прочие задачи виснут к хуям, пока текущая подпрограмма не закончит свою работу и не попустит поток исполнения.

                            Нахреначь примитивную недоос с недопланировщиком через прерывания от таймера, и будет тебе счастье.
                            Ответить
                            • Я же говорю - дерьмо 20 летней давности.
                              Я где-то недавно оставлял камент, чем я занимался в юности.
                              Там тоже была "недоос" с подобной вытесняющей многозадачностью, весила килобайт 100 наверное.
                              Бывает ещё кооперативная, где задача должна сказать sleep() или ещё какую-то хуйню (ладно, "wait for some activity" обычно), чтобы недоОС могла её переключить на другую.
                              Похоже на детские трёхколёсные велосипеды. Пока мимо пролетают технологичные машины с автопилотом.
                              Ответить
                            • так пока задача 1 выполняется задача 2 всё равно висит, хоть через цикл хоть через таймер
                              Ответить
                          • > Я знаю почему пригорает у неосилятора.

                            Видишь ли. Я не "не могу" осилить плюсы. Я просто не хочу их осиливать, т.к. чем больше я узнаю плюсов, тем больше я вижу в них говна и хренового дизайна. Это было очень плохой идеей, делать из языка Си подобие высокоуровневого языка. Нужно делать другой нормальный высокоуровневый язык, или ждать его появления

                            https://i.imgur.com/jBoAChW.png
                            Ответить
                            • Но при этом ты топишь за си, который еще хуевей плюсов.
                              Ответить
                              • На самом-то деле язык Си я тоже считаю достаточно ограниченной хуйней. НО для своей узкой ниши (кроссплатформенный ассемблер) он подходит достаточно хорошо.

                                Язык C++ же позиционируется, насколько я понял, как некий мультипарадигменнный высокоуровневый язык общего назначения, который к тому же и не запрещает низкоуровневую байтоеблю. Но высокоуровневые фичи плюсов по сравнению с нормальными языками высокого уровня (вроде LISP или какого-нибудь хаскеля, ерланга) являются просто таки абсолютнейшим говном и отстоем.

                                См. также: http://govnokod.ru/20947#comment348009
                                Ответить
                              • Ты видимо не совсем понимаешь мое отношение к Си и C++
                                Я не ненавижу ни то, ни другое, но мне это не мешает считать эти языки говном.

                                Проблема C в убогом препроцессоре с убогими макросами, негомоиконности, отсутствии механизмов метапрограммирования, обобщенного программирования. Язык слишком низкоуровневый, на нем не очень-то удобно писать что-то большое. Низкий уровень абстракции.

                                Проблема C++ в том, что C++ это убогая и кривая говнонадстройка над C которая задумывалась для того, чтобы добавить всякую высокоуровневую питушню. Притом если взять тот же прием метапрограммирования на шаблонах, то плюсовые шаблоны изначально не задумывались для того, чтобы на них занимались метапрограммированием, считали в компилтайме числа Фибоначчи и прочей ебанистикой. У Мейерса именно так и написано, что метапрограммирование шаблонов (template metaprogramming – TMP) было именно открыто, никто изначально в языке это не задумывал:

                                > C++ не предназначался для метапрограммирования шаблонов, но с тех пор, как технология TMP была открыта в начале 90-х годов, она оказалась настолько полезной, что, вероятно, и в сам язык, и в стандартную библиотеку будут включены расширения, облегчающие работу с TMP. Да, TMP было именно открыто, а не придумано. Средства, лежащие в основе TMP, появились в C++ вместе с шаблонами. Нужно было только, чтобы кто-то заметил, как они могут быть использованы изобретательным и неожиданным образом.

                                Ну т.е. тупо взяли заменитель препроцессора, и начали им считать всякие Фибоначчи и прочую срань.

                                Ах да, потом еще придумали всякую херню, типа constexpr-ов, которые типа считаются на этапе компиляции, но это такое говно, что мне даже лень повторяться, в этих constexpr-ах всю херню надо возвращать через return, нельзя юзать malloc, memcpy и прочую хрень, которая не вписывается в этот навязываемый языком говнофункциональный стиль. http://govnokod.ru/19105#comment307730
                                Ответить
                                • (это была цитата из
                                  http://dump.bitcheese.net/files/pimarut/%D0%93%D0%BE%D0%B2%D0%BD%D0%BE%D0%BA%D0%BE%D0%B4_%2320924_%E2%80%94_C___%E2%80%94_%D0%93%D0%BE%D0%B2%D0%BD%D0%BE%D0%BA%D0%BE%D0%B4.%D1%80%D1%83.html
                                  )
                                  Ответить
                                • А какой результат malloc времени компиляции тебя бы устроил?

                                  И да, как будто если начал писать на крестах, то сразу надо обмазаться параметрическим полиморфизмом и компайл-тайм оптимизациями, вместо того, чтобы хотя бы воспользоваться пользой RAII, которой нет в сраной сишке?
                                  Ответить
                                  • > А какой результат malloc времени компиляции тебя бы устроил?

                                    Как если бы у меня было бы две точки входа, и одна точка входа выполнялась бы "во время компиляции". И malloc-нутая из той точки входа память может быть передана особой зарезервированной функции, и тогда эта память будет использована для инициализации некоего статического массива, который уже будет внедрен в исходный код на следующей стадии компилирования(когда компилтайм-кодо/данно-генерация закончится), и использоваться нормально-скомпилированной программой как обычный проинициализированный массив.
                                    Ответить
                                    • но в чем преимущество malloc, если исходя из твоих слов (я всё ещё не уверен, что я правильно понял) ты на этапе компиляции уже знаешь размер массива? зачем тебе куча в этом случае?
                                      мы ведь снова обсуждаем таблицу косинусов?
                                      Ответить
                                      • Может быть я хочу переиначить код таким образом, чтобы таблица синусов была больше (для большей точности) или меньше (для экономии ПЗУ в говноконтроллере). И задавать эту херню флагами компиляции. И тогда я уже нихрена в точности не знаю.
                                        Ответить
                                        • типа вот так?
                                          https://godbolt.org/g/TVZg28
                                          Ответить
                                          • http://funkyimg.com/u2/1357/921/337303594fd40397ca.jpg
                                            Ответить
                                          • А кстати, как насчет адаптивной дискредитации для этой говнотаблицы поиска? http://peredacha-informacii.ru/adaptivnaja-diskretizacija.html

                                            И вообще, на кой хер в таблице синусов хранить синус где-то дальше чем от 0 до pi/2 ? Ведь дальше можно все это говно отзеркаливать
                                            Ответить
                                            • тебе виднее, как наиболее эффективно намазывать это говно
                                              Ответить
                                              • Это говно в том то и суть, что через шаблоны хер намажешь, т.к. говноплавучка в шаблонах не хавается нормально
                                                Ответить
                                                • слышу звон да не знаю где он? Плавучка в шаблонах неуместна только в виде шаблонного параметра
                                                  Ответить
                                                  • Вот у тебя есть гипотетический говноконтроллер с плавучкой, где нет естественно никаких аппаратных синусов, но есть умножение-деление-сложение-вычитание и нахождение остатка от деления плавучки.

                                                    Нужно построить таблицу синусов, но построить ее надо очень оптимально. В областях, где график синуса хорошо приближается прямой линией(т.е. мы должны задавать, какие нам допустимы погрешности), не будут непрерывно тыкаться точки в таблицу поиска. Фактически, таблицы поиска в привычном смысле не будет, будет if, который проверяет интервал, и по линейной формуле считает это говно.

                                                    Вот когда тупо делаем таблицу поиска, например синусов от 0 до pi/2 с шагом pi/128 то там тупо будут равномерно идти все это говно, ну типа в таблице будет значение синуса sin(0), sin(pi/128), sin(2pi/128) ну и таким вот макаром эта хуита шагает одинаковыми шагами вплоть до sin(pi/2). Но на деле-то такая хуйня нахуй не нужна, можно эти злоебучие точки расставить таким образом, чтоб между ними была практически прямая, ну типа считаем для заданных допусков(погрешностей) что между sin(0) и sin(30pi/128) график функции меняется настолько линейно, что можно не хреначить кучу точек sin(1pi/128) sin(2pi/128) sin(3pi/128) sin(4pi/128) а тупо хуйнуть интервал через if(плавучка < 30pi/128) {вот_тебе_уравнение_прямой_считай_по_ней ();} и вот так всю эту парашу можно разбить на такие сраные фрагменты, это блядь называется кусочно-линейная интерполяция/аппроксимация http://eelib.narod.ru/toe/Novg_2.01/29/Image353.gif https://files3.vunivere.ru/workbase/00/04/01/95/images/image001.gif или адаптивная дискретизация http://peredacha-informacii.ru/images/adaptivnaja-diskretizacija02.gif
                                                    в общем суть этого говна чтобы приблизить кусок синуса кучей прямых на разных, еби его в рот, интервалах, и чтобы при этом выполнялось условие того, чтоб погрешность этой еботни не превышала определеного значения. Кто-нибудь в здравом уме будет подобную поеботу писать на говношаблонах?
                                                    Ответить
                                                    • И вообще, как писать подобную поеботу, если нельзя использовать плавучку в качестве шаблонного параметра?
                                                      Ответить
                                                      • Используй рациональные числа, а плавучку из них делай потом.
                                                        Ответить
                                                    • вот прям сейчас занимаюсь тем, что оптимизирую Фурье через шаблоны, в т.ч. там есть и таблица синусов/косинусов на constexpr

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

                                                        Очевидно же, что линейная аппроскимация между двумя точками должна делаться уже в рантайме, а задача шаблонов-констэкспров заключается в том, чтобы создать множество опорных значений, между которыми будет эта самая линейная аппроксимация работать, и эти опорные значения вшить в некий нагенеренный код, который будет работать как двоичный поиск
                                                        if (x < некое_значение_1)
                                                          if(x < некое_значение_2)
                                                            if(x < некое_значение_3)
                                                        ...

                                                        Короче, вот тут в говноинтерпретаторе питона наанроллен двоичный поиск через ифы
                                                        https://github.com/python/cpython/blob/8e1da5823b4dabbc5e60f8ee27411070a37804ef/Modules/_decimal/libmpdec/mpdecimal.c#L134

                                                        похожую хрень через проверки диапазонов флоатов сделать, и чтоб оптимально, за O(log n) проверок чтоб было
                                                        Ответить
                                                      • > А если хочешь аппроксимировать в рантайме, то таблица генерируется шаблонами очень и очень легко

                                                        И анролл из цепочек if-ов тоже легко делается?
                                                        Ответить
                                                        • а зачем цепочки if'ов и двоичный поиск то? У тебя есть угол a для которого нужно посчитать sin, есть результаты для a[0..n], ну так аппроксимируй между a[k], k = floor(a) до a[k+1], (k+1) = ceil(a). Округлять твой мк умеет, сам сказал
                                                          Ответить
                                                          • > зачем цепочки if'ов и двоичный поиск то
                                                            Он хочет неравномерный шаг, чтобы и точность набрать и слишком много опорных точек не юзать.
                                                            Ответить
                                          • Кстати, при вычислении констант происходят ошибки округлений, в то время как некоторые константы можно предствать абсолютно точно +-1 и +-1/2 и 0 например. Так что это плахая идея генерить табличные даблы вычислениями (тем более, на шаблонах)
                                            Ответить
                                            • В общем, для генерации таблицы поиска лучше подойдет нечто, чем можно было бы с максимально возможно точностью (насколько это допускается самим представлением чисел в IEE754) высчитать значения для нужных точек. Можно для этого например использовать тот факт, что синус нуля равен нулю, а синус pi/2 равен 1, ну и дальше плясать через формулу половинного угла
                                              https://wikimedia.org/api/rest_v1/media/math/render/svg/8741dcd4f11fde7bfbd897853053257aad5d8921
                                              и вот так для всех нужных точек через какую-нибудь парашу (надо чтоб floating-point arithmetic with arbitrary precision было, можно и на говнопитоне через mpmath, и на Си, через MPIR, или с каким-нибудь маткадом можно потрахаться, см. https://www.mathworks.com/help/symbolic/vpa.html) посчитать это говно для нужных точек настолько точно, насколько это вообще возможно для говноплавучего представления, чтобы не было блядских погрешностей в самой метушне.
                                              Ответить
                                              • Хотя вообще да, написать недоCAS на шаблонах для этого все же можно (раз они тьюринг-полные) но это будет такой ****** что вряд ли кто-то будет в здравом уме не по приколу таким маразмом заниматься, и компилироваться весь этот бред будет очень долго
                                                Ответить
                                                • Тебя всё не попустит?
                                                  Ты не поверишь, но 99.9999% программистов в жизни нахер не сдалось рассчитывать таблицу косинусов переменного размера.
                                                  А если и сдастся - врядли они это будут делать на крестошаблонах и констэкспрах только лишь потому, что могут, они же не коты.
                                                  И всё вышеописанное не означает то, что отныне крестошаблоны не нужны никому, ведь с ними было неудобно (хоть и возможно!) решить задачу генерации в компайл-тайме твоей специфичной задачи.
                                                  И да, при различных переменных алгоритмах, которые ты тут рассказывал (деление круга на неравномерные части для получения лучшей/худшей точности на некоторых участках) как раз шаблоны выиграют тем, что у тебя непосредственно знания о способе деления круга будут лежать в одном месте, а не будут размазаны по нескольким модулям (одним на питоне, который дёрнется во время компиляции, а другим - в приложении, когда настанет необходимость обращаться к этой посчитанной вундервафле).
                                                  Ответить
                                                  • >как раз шаблоны выиграют тем, что у тебя непосредственно знания о способе деления круга будут лежать в одном месте

                                                    Бред. С тем же успехом я могу куски кодогенератора каким-то хитрым образом вкорячивать в сишные комментарии, и потом особой херней препроцессировать подобный бред, и чтоб на месте комментов выплевывался нужный код.
                                                    И подобная херь уже есть, например https://nedbatchelder.com/code/cog/ http://re2c.org/examples/example_01.html
                                                    Ответить
                                                    • > каким-то хитрым образом вкорячивать в сишные комментарии

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

                                                          > каким-то хитрым образом вкорячивать в сишные комментарии
                                                          ЛЯМБДЫ В ЖАБЕ НЕНУЖНЫ, НО КОГДА НУЖНЫ, Я ВКОРЯЧИВАЮ КОДОГЕНЕРАТОР
                                                          Ответить
                                                          • >Иногда (такое случается крайне нечасто, конечно, это скорее признак крайне застарелых парадигм, неуместных для беседы благородных донов) программист пишет крестошаблон, потому что ему нужен полиморфизм, а не число фибоначчи.

                                                            Да как такое вообще кому-то могла прийти в голову столь крамольная мысль? Ведь настоящие программисты на C++ едят котлеты ложкой, суп вилкой, рубят пилой, пилят топором, микроскопом забивают гвозди, а молотком... молотком себя херачат по голове, уничтожая остатки мозгов
                                                            Ответить
                                                    • Уже не раз обсуждали, что нужно просто заменить препроцессор напхп. Хотя я конечно предпочел бы питон.
                                                      Ответить
                        • >Оторвись уже от своего восьмибитного говна и осознай, что есть процессоры с более чем одним ядром.

                          И как ты предлагаешь из кода, утыканного этими shared_ptr выкинуть их все к херам, если я этот код хочу запускать на процессоре с одним ядром и без гипертрединга, но не хочу получать совершенно нахер не нужный оверхед от shared_ptr?

                          >shared_ptr нужен редко, но без него было бы грустно...

                          Мне вот почему-то кажется, что его чаще используют как недоGC (пусть там вот само находит, когда этот кусок можно освобождать) а не как какой-то вспомогательный механизм для многопоточности. К тому же нормальных контейнеров, которые были бы thread-safe не только на чтение, в плюсовой стандартной библиотеке попросту нет. Как и асинхронщины. Это все надо тащить из буста или другого внешнего говна

                          >Никто и не говорит, что это GC, откуда ты это взял?

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

                            Кажется ему... Когда работаешь в однопоточной среде, для отслеживания времени жизни объекта хватит и unique_ptr, и то больше для корректности исключений и early return.

                            > И как ты предлагаешь из кода, утыканного этими shared_ptr выкинуть их все к херам

                            в однопоточном приложении - то? автозамена shared_ptr -> unique_ptr и в местах где "не могу скопировать unique_ptr" организуем move или передачу по ссылке (смотря что надо).

                            > Но сходные черты есть. Это не GC, это огрызок от GC.

                            ты не понимаешь как работает shared_ptr или ты не понимаешь как работает GC?
                            Ответить
                            • >Когда работаешь в однопоточной среде, для отслеживания времени жизни объекта хватит и unique_ptr

                              unique_ptr это довольно примитивная по своей сути ерунда, которая мне попросту не нужна. Мне вполне достаточно моих мозгов и обычных malloc()/free() для такого, т.е. не нужно вообще вводить понятие "владение", "область видимости" и тому подобной хуйни, а просто достаточно пересылать сырой указатель и освобождать его, когда настанет нужный момент.

                              >в однопоточном приложении - то? автозамена shared_ptr -> unique_ptr и в местах где "не могу скопировать unique_ptr" организуем move или передачу по ссылке (смотря что надо).

                              Т.е. это мне все руками надо делать, да? Ну отлично!

                              >ты не понимаешь как работает shared_ptr или ты не понимаешь как работает GC?

                              shared_ptr это хрень для подсчета ссылок. Когда что-то там не ссылается на объект, мы декрементируем некую хрень. В GC тоже реализован механизм подсчета ссылок, и работает там эта хрень таким же образом.
                              Ответить
                              • > Мне вполне достаточно моих мозгов и обычных malloc()/free() для такого

                                с обычными malloc/free надо освобождать ресурсы ручками в каждой точке выхода из функции. Поэтому сишники городят всякие goto и седьмой уровень вложенности if'ов на ровном месте
                                Ответить
                                • Самое веселье начинается когда сишник хочет экономить на копированиях и передавать/возвращать сырой указатель в другие функции. Вот тут вся эта радость с "владением" и всплывает (и хорошо, если она хоть прокомментирована).

                                  З.Ы. Причем каждый сищник искренне верит, что он то точно знает, когда настанет "нужный момент".
                                  Ответить
                                  • когда резьбовой болт начинает стимулировать простату
                                    Ответить
                        • > сколько для компактификации кучи.

                          оптимизации для GC придумали уже потом. Основная задумка была чтобы у анскиллябр код не тек и не вылетал после попыток эти течки исправить.
                          Ответить
                          • Ящитаю, GC нельзя использовать:
                            - В драйверах/бутлоадерах
                            - В имбеддщине
                            - В uber-highload-hard-realtime-zero-latency питушне

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

                                    Не факт — сначала должно кончиться место. А если все в дедлоке, то оно может и не кончиться...
                                    К тому же, мутекс обычно можно отпускать только из того же треда, который этот мутекс захватил.
                                    Ответить
                              • https://hackage.haskell.org/package/base-4.10.0.0/docs/System-IO.html#v:withFile
                                Ответить
                                • Ну это не то чтобы прям "нормально". Скорее надо на STM ссылаться, там мутексы отпускать не надо. Или какой-нибудь ResourceT.
                                  Ответить
                                  • Ты перечислил абстракции другого рода. Я намекал, что RAII -- это настолько примитивно, что аналог легко написать ручками.
                                    Ответить
                                    • > RAII -- это настолько примитивно

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

                                        Честно говоря, до того, как в языке появились rvalue-ref и мув-семантика, в плюсах это тоже не очень весело было делать.
                                        Ответить
                          • > Основная задумка была чтобы у анскиллябр код не тек

                            Основная задумка была чтобы можно было написать
                            (reduce #'+
                                    (mapcar #'(lambda (x) (* x x))
                                            '(1 2 3 4 5)))
                            и не думать, где размещать промежуточные результаты
                            Ответить
                        • > GC полезен не столько для сбора циклов (эту проблему можно самому решить, если продумать жизненный цикл), сколько для компактификации кучи.

                          Компактификация кучи (дефрагментация хипа) может быть реализована и без GC, см. http://govnokod.ru/18748#comment369745

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

                            Тот же троллейбус, только из буханки.
                            Ответить
                            • Не, это больше похоже на MMU, чем на GC.
                              Ответить
                              • Я бы сказал, что "реализация компактификации" без ГЦ — это использование арен и специализированных аллокаторов.
                                К примеру, веб-сервер может аллоцировать единый кусок памяти (2-4 МБ, к примеру, но царь лучше знает, сколько памяти нужно его программам) для обработки каждого запроса, и использовать этот кусок для аллокаций всех объектов в рамках запроса. А когда запрос обработан, можно дропать всю арену целиком.
                                Ответить
    • Чо сука не ждали?
      Почему залогиненный гк работает хуевее, чем разлогиненный?
      Ответить
      • У меня так же. Вероятно, новый бекенд недостаточно разработан, чтобы вместить столько залогиненных членов сообщества.
        Ответить
        • ГК всё-таки переехал на новый бекенд?
          Ответить
          • Я не уверен. Но что-то Страйко всё-таки сломал изменил, раз гости не пишут и главная со стоком после логина периодически тормозят? Или хостер ввёл санкции против России какие-то ограничения?
            Ответить
            • Страйкер послушался и перебанил все учетки с паролем 123?
              Ответить
              • А я всё голову ломаю, почему сейчас такая активность...

                Хорошо, что у меня пароль 456.
                Ответить
              • Лето, каникулы.
                Ответить
        • Целых 5?
          Ответить

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