- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
int function(void) {
static int i, state = 0;
switch (state) {
case 0: /* start of function */
for (i = 0; i < 10; i++) {
state = 1; /* so we will come back to "case 1" */
return i;
case 1:; /* resume control straight after the return */
}
}
}
"case 1" - не видим в данном контексте...
Видимо, при каких-то настройках в каком-то древнем стандарте такое можно было.
А вообще.
http://ru.wikipedia.org/wiki/%D0%A3%D1%81%D1%82%D1%80%D0%BE%D0%B9%D1% 81%D1%82%D0%B2%D0%BE_%D0%94%D0%B0%D1%84% D1%84%D0%B0
i всегда определено. Если прыгаем внутрь цикла, то просто подходим к концу итерации.
Если state 0, то меняем на 1, иначе, если i меньше 10, увеличиваем i. Нахера выпендриваться?
Или надрезать шаблон, как вот первому комментатору.
Бессмысленно
- там, я так полагаю, функция рассчитана на циклическое использование или для перерисовок... - как вариант можно использовать для подсчёта количества перерисовок :)
тут нужно доработать:
теперь цикл внутри - работает =Ъ
тут — 14, void, void...
-- как-то стрёмно, стало, что можно было прям в тело цикла запрыгнуть, и чтобы такое работало :(
и честно, - даже удивлён был, что ни слова не сказал компилер, что так делать не хорошо... О_о
Хотябы потомучто этот код не потоковобезопасный, тк использует общие для разных потоков static переменные (если, кончно, это не входило в планы разработчика).
К тому же после завершения цикла перестаёт возвращать из функции вообще какие либо значения. После завершения цикла просто возвращает случайный мусор.
Ну, тут я не сильно знаком с тем, что будет возвращаться функцией, если ничего не будет возвращаться в её теле. Предположил, что она возвращать будет что-то на подобии указателя с недотипом void
Какой-то неудачный пример.
ряд => поток
водитель => компилятор
Насколько я знаю, потоки порождаются процессами.
А то расскажите мне курс, запишите за меня в тетрадку, покажите видеокурс и запомните за меня...
Опасны столкновения между машинами.
static - это и есть то самое "столкновение" между потоками.
по разным рядам.
>Опасны столкновения между машинами.
Взаимоисключающие параграфы?
Функция вернёт случайный мусор, тот, что остался в регистре eax, если не использовать return.
В данном коде есть случаи, когда return не вызывается. Тогда мы получим мусор.
Что-бы стало лучше - нужно state=0 после цикла поставить и "goto" на начало функции.
Предложние не согласовано.
Корутины (Coroutine) позволяют прерывать вычисления функции с возвратом значения (return) и продолжать с того же места, на котором остановились.
В C# для этого используется оператор yield.
Пожалуй, в данном говнокоде сделано не очень аккуратно, но смысл передаёт.
Интересно, существуют ли альтернативные реализации корутин на С++?
http://www.chiark.greenend.org.uk/~sgtatham/coroutines.html
давно ничего подобного на гк не было - все окупировало пхп.
Это совершенно не так. Этот паттерн, с некоторой натяжкой, называется корутина и я выше это описал в http://govnokod.ru/5186#comment68330
>по стандарту языка такое работать не должно
Должно.
Это функция при каждом вызове вернёт следующее значение переменной i из цикла (и так от 0 до 9).
Тоесть Console::Write(function()) выведет на экран 0.
Следующий вызов Console::Write(function()) выведет на экран 1 и так до 9.
Дальше там в коде косяк, тк не возвращается зачение return'ом, но с варнингом скомпилируется и будет возвращать мусор.
В С++ при даной реализации она почти ничего не стоит.
Но всё же лучше этого не делать, а воспользоваться более подходящими для этого инструментами, чем Си.
Идею я теперь понял
> Но всё же лучше этого не делать
А я и не собирался
>понять не могу
>не могу понять
Просто загуглите про корутины или хотябы сходите по моей ссылке, в которых есть кривенькая рализация всё тех же корутин на чистом Си.
Ни кто с этим и не спорит. Автор расчитывает, что функция со свитча начинается.
>компилятор и оптимизирует данный код
Оптимизация тут не причём. Этот код - лишь эмуляция начала функции с return через свитч.
Если ссылку так и не нашли, то приведу снова, сходите:
http://www.chiark.greenend.org.uk/~sgtatham/coroutines.html
Только там про корутины из текущего говнокода написано ближе к середине.
Для говнокода - да.
> Если ссылку так и не нашли
Да я вас отлично понимаю, не надо думать, что я не знаю, что такое сопрограмма. Я вообще как бэ другое хотел сказать.
Я Вас послушаю. Что Вы хотели сказать?
Попробуйте повторить, возможно я не всё понял.
Мне показалось, что не всё внятно расписано, извиняюсь... :-[
> Я имею ввиду другое, а именно, что автор утверждает (как я уже сейчас понял), что управление будет передано после retrun, это не так (передано оно конечно будет туда, но не сразу), для этого достаточно вставить что-нибудь перед switch'ем
>>для этого достаточно вставить что-нибудь перед switch'ем
Ни кто с этим и не спорит. Автор расчитывает, что функция со свитча начинается.
Теперь понятно?
http://govnokod.ru/5153
Школоте для общего развития: http://ru.wikipedia.org/wiki/Устройство_Даффа
;)
Как в мире С всё... эээ, демократично, хоть бы одна знаменитость имела профильное образование и после защиты устроилась работать с компьютерами...
альфа-наложение, facepalm.sgi
вообще у него даже публикация есть, хотя непонятно чего там исследовать, что характерно, тогда работал на мамашу Белл, как и остальные
http://govnokod.ru/5186#comment68340
Так, что думаю удивляются только единицы.
В любом случае даффдевайс, как и этот код - говно говном.
Его тоже надо сюда запостить. Бесполезная конструкция, которой зато можно троллить паскалистов (или сишников, смотря как её преподнести).
цппешники не ебут себе мозги
_func function;
while(1)
std::cout << function();
1)Для многопоточных приложений придётся просить (комметарием) создавать функциональный объект в стеке.
2)Будь код чуток сложнее, например:
- ваш код уже работать не будет. В оригинальном коде управление передаётся сразу к return при повторном входе в функцию.
Впрочем, для данного конкретного случая это намного лучше приведённого выше говнокода 5186. :)
нет. могут создавать где угодно, главное, чтоб не было совместного использования одного объекта (каждый объект имеет свое состояние).
>>ваш код уже работать не будет. В оригинальном коде управление передаётся сразу к return при повторном входе в функцию.
это костыль, созданный для того, чтобы избежать return
А потом совершенно случайно не заметете, как станете использовать один из объектов в нескольких потоках. ))
При первом входе возвращает 0, потом 1, потом 2 и тд до 9.
Мне понравилась идея - первый раз подобное встретил =)
Контекст пропихнуть, макросом обмазать и вполне практично.