Почему setjmp не сохраняет стек? - PullRequest
2 голосов
/ 29 августа 2011

Почему setjmp не сохраняет стек?
Рассмотрим следующий код:

#include <iostream>

jmp_buf Buf;
jmp_buf Buf2;

void MyFunction()
{
    for(int i = 0; i < 5; i++)
    {
        std::cout << i << std::endl;
        if(!setjmp(Buf))
            longjmp(Buf2, 1);
    }
}

int main (int argc, const char * argv[])
{
    while(true)
    {
        if(!setjmp(Buf2))
        {
            MyFunction();
            break;
        }
        longjmp(Buf, 1);
    }
    return 0;
}

Что я исключаю, это то, что код будет переходить вперед и назад от основного к функции и обратно увеличивать число печати каждый раз.
На самом деле происходит то, что он печатает 0, а затем 1 бесконечное количество раз. это как если бы когда он возвращается в функцию, стек сбрасывается до значений по умолчанию. почему он это делает? Можно ли как-нибудь сохранить его тоже?
Я знаю, что setjmp и longjmp даже хуже, чем goto, когда дело доходит до стиля кодирования и читаемого кода, но я сейчас экспериментирую, и этот код, вероятно, никогда не увидит свет пригодного для использования приложения.

1 Ответ

2 голосов
/ 29 августа 2011

Потому что, к сожалению, это не так, как работает setjmp.setjmp копирует текущий указатель команды и набор регистров в буфер перехода, но не копирует стек (очевидно, потому что стек огромен).Похоже, вы хотите использовать какие-то методы на основе сопрограмм.Если вы хотите сделать это самостоятельно, ознакомьтесь с процедурой ucontextd (ucontext.h) http://compute.cnr.berkeley.edu/cgi-bin/man-cgi?ucontext.h+3, которая поможет вам выделить дополнительные стеки потоков и управлять ими.

http://swtch.com/libtask/), который поможет сделать это за вас. Или, если вы хотите сделать это самостоятельно, вы должны взглянуть на код libtask (также доступный по этой ссылке). Его довольно легко прочитать, так что это хороший ресурс.

...