Няшная / Говнокод #26982 Ссылка на оригинал

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
/* https://habr.com/ru/company/piter/blog/491996/

Пусть в Python такая штука и называется генератором, в языке C++ она
называлась бы корутиной. Пример взят с этого сайта: https://masnun.com/2015/11/13/python-generators-coroutines-native-coroutines-and-async-await.html

def generate_nums():
     num = 0
     while True:
          yield num
          num = num + 1	

nums = generate_nums()
	
for x in nums:
     print(x)
	
     if x > 9:
*/

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>

#define START 0
#define YIELD 1

typedef struct 
{
  uint8_t jmpto;
  int num;
} coroutine_state;


int generate_nums(coroutine_state *state)
{
  switch(state->jmpto)
  {
    case START: break;
    case YIELD: goto yield;
  }
  while (true)
  {
    state->jmpto = YIELD; return state->num; yield: // какая питушня

    state->num = state->num + 1;
  }
}




int main(void)
{
  int x;
  coroutine_state st = {START, 0};
  while(true)
  {
    x = generate_nums(&st);
    printf("%d\n", x);

    if (x > 9)
    {
      break;
    }
  }
  return EXIT_SUCCESS;
}

Попробовал переписать эту ко-ко-корутину c питуха на Си - получилась какая-то херня нечитаемая. что еще раз доказывает, что корутины нахуй не нужны

К тому же в крестопарашном говне они требуют хип, а это нахуй не нужно на самом-то деле.

Запостил: j123123 j123123, (Updated )

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

  • Собственно, эту функцию можно даже так пропатчить, поскольку "корутинный ретурн" тут только один
    int generate_nums(coroutine_state *state)
    {
      switch(state->jmpto)
      {
        case START: state->jmpto = YIELD; break;
        case YIELD: goto yield;
      }
      while (true)
      {
        return state->num; yield: // какая питушня
    
        state->num = state->num + 1;
      }
    }
    Ответить
      • Блядь ебучие уиелд. Ненавижу его.
        Ненавижу потому читаю постоянно его "елда"
        Ответить
          • Елда может также означать:

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

    Требуют аллокацию, а не хип.

    Ну и конпелятор вроде как имеет право не юзать хип, если ему очевидно, что корутина за пределы функции не вылетает.

    З.Ы. Один фиг это лучше чем context switch и новый стек под каждую корутину.
    Ответить
    • а аллоцироваться можно, например, в заранее выделенной стат памяти?
      Ответить
      • Да, там всего одна аллокация. Но надо как-то угадать размер буфера.

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

        А если конпелятор (1) доказал, что корутина юзается только внутри твоей функции, (2) видит полную реализацию, а не прототип, то он и сам не будет юзать аллокатор.
        Ответить
        • >т.к. ты не видишь её локалки.
          было бы круто сделать такую урезанную корутину, в которой ты обязан в сигнатуре указывать все локалки, чтобы копулятор сразу понимал размер "стека", ну как в c89, и без всяких аллока и vla
          Ответить
          • Да там всё равно проблемы остаются. Корутина может звать другие корутины. И их состояние либо выделяется на куче либо эмбеддится в стейт вызывающей корутины.

            Т.е. тебе надо видеть не только локалки, но и полную реализацию всего говна, которое вызывает текущая корутина. И так далее.

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

              А то пишут, пишут... линкер, аллокации какие-то... Голова пухнет. Взять бы всё, да и засунуть в одну единицу трансляции.

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

              Если на этапе компиляции можно доказать, что корутина не выделяет у себя на стеке хуйпойми сколько байтиков, то проблема решается без всякой питушни с аллокациями. Просто делаем структуру, которая хранит значения локальных переменных для конкретной корутины и то место, с которого надо продолжить исполнение этой самой корутины после yield хуйни (если там их несколько) и в эту корутину передаем в качестве аргумента указатель на такую структуру.

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

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

            Т.е. здесь вообще только в рантайме можно размер узнать.
            Ответить
  • Царь и Гомоиконы

    Здесь сразу становится понятно - почему С++ развивается в сторону языка-кодогенератора. Статический язык - это язык высшего порядка - это мета-язык. Человек не должен писать код. В какой-то степени это понимают запартыши и какие-то потуги в этом направлении у них ведутся, но всё это бесполезно. Это примитивная, бездарная херня, которая никому не нужна. Как-нибудь я подробней об этом(о запарте и почему она обречена) расскажу.

    На самом деле, открою тайну, но сишка так же является скриптухой. Правда с одним нюансом. Из-за того, что там ничего нет - там никакие проблемы особо не проявляются. Потому как любой код на сишке - это мономорфная кодогенерация(ручная). Т.е. используя сишку - мы просто в 90% времени делаем обезьянью работу.

    И здесь так же можно понять - почему я всегда хейтил и хейчу C++. Си с классами - это чистая скриптуха. Уже полиморфная. А вот C++ как мета-язык не состоятелен. Что мы хотим от мета-языка? Мы хотим, чтобы он производил то, что мы можем произвести руками(с теми же, либо лучшими свойствами). Но он не производил. И вот только с gnu++2a - язык стал в какой-то мере полноценным и позволяет заменить си.
    Ответить

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

Переведи на "PHP", guest!

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


    8