Этот вопрос возник из Практического использования 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.