Этот вопрос исходит из Практического использования setjmp и longjmp в C и Как реализовать сопрограмму в цикле for в c что я спросил.
jmp_buf bufferA, bufferB;
void routineB(); // forward declaration
void routineA()
{
int r = 0;
printf("(A1)\n");
if (setjmp(bufferA) == 0) {
r++;
alloca(2048);
routineB();
}
printf("(A2) r=%d\n",r);
if (setjmp(bufferA) == 0) {
r++;
longjmp(bufferB, 1);
}
printf("(A3) r=%d\n",r);
if (setjmp(bufferA) == 0) {
r++;
longjmp(bufferB, 1);
}
printf("(A4) r=%d\n",r);
}
void routineB()
{
int r = 0;
printf("(B1)\n");
if (setjmp(bufferB) == 0) {
r++;
longjmp(bufferA, 1);
}
printf("(B2) r=%d\n", r);
if (setjmp(bufferB) == 0) {
r++;
longjmp(bufferA, 1);
}
printf("(B3) r=%d\n", r);
if (setjmp(bufferB) == 0) {
r++;
longjmp(bufferA, 1);
}
printf("(B4) r=%d never reach\n", r);
}
int main()
{
printf("main\n");
routineA();
return 0;
}
Я изучаю реализацию сопрограммы C. и пытаюсь увидеть, что произошло в стеке после longjmp
.
Вопрос 1:
Что за волшебство делает стек routineB
живым после использования alloca(2048)
? Я слышал, что alloca
это зло, но почему он делает стек расширенным. Должен ли я использовать это так?
Выход:
main
(A1)
(B1)
(A2) r=1
(B2) r=1
(A3) r=2
(B3) r=2
(A4) r=3
Вопрос 2:
После удаления alloca(2048)
. это дает другой результат после того, как компилятор отключает оптимизацию (-O2).
-O0
main
(A1)
(B1)
(A2) r=1
(B2) r=6356584
(A3) r=2
(B3) r=6356584
(A4) r=3
-O2
main
(A1)
(B1)
(A2) r=1
(B2) r=0
(A3) r=1
(B3) r=0
(A4) r=1
если это не неопределенно, как заставить код вести себя так же? если это так, пожалуйста, забудьте Q2.
longjmp
как особыйreturn
. - person JustWe   schedule 23.05.2018longjmp
не всегда возврат. Он завершает функцию только в том случае, если соответствующийsetjmp
был в функции ранее в наборе вложенных вызовов. Еслиsetjmp
находится в той же функции, это похоже на обычныйgoto
. Такжеsetjmp
может быть на много ступеней ниже вложенности. Так что это совсем не похоже наreturn
. - person Ajay Brahmakshatriya   schedule 23.05.2018longjmp
иsetjmp
. - person JustWe   schedule 23.05.2018