Breaking out of a loop from within a function called in that loop

后端 未结 14 1029
盖世英雄少女心
盖世英雄少女心 2020-12-30 20:31

I\'m currently trying to figure out a way to break out of a for loop from within a function called in that loop. I\'m aware of the possibility to just have the

14条回答
  •  陌清茗
    陌清茗 (楼主)
    2020-12-30 20:41

    break, like goto, can only jump locally within the same function, but if you absolutely have to, you can use setjmp and longjmp:

    #include 
    #include 
    
    jmp_buf jump_target;
    
    void foo(void)
    {
        printf("Inside foo!\n");
        longjmp(jump_target, 1);
        printf("Still inside foo!\n");
    }
    
    int main(void) {
        if (setjmp(jump_target) == 0)
            foo();
        else
            printf("Jumped out!\n");
        return 0;
    }
    

    The call to longjmp will cause a jump back to the setjmp call. The return value from setjmp shows if it is returning after setting the jump target, or if it is returning from a jump.

    Output:

    Inside foo!
    Jumped out!
    

    Nonlocal jumps are safe when used correctly, but there are a number of things to think carefully about:

    • Since longjmp jumps "through" all the function activations between the setjmp call and the longjmp call, if any of those functions expect to be able to do additional work after the current place in execution, that work will simply not be done.
    • If the function activation that called setjmp has terminated, the behaviour is undefined. Anything can happen.
    • If setjmp hasn't yet been called, then jump_target is not set, and the behaviour is undefined.
    • Local variables in the function that called setjmp can under certain conditions have undefined values.
    • One word: threads.
    • Other things, such as that floating-point status flags might not be retained, and that there are restrictions on where you can put the setjmp call.

    Most of these follow naturally if you have a good understanding of what a nonlocal jump does on the level of machine instructions and CPU registers, but unless you have that, and have read what the C standard does and does not guarantee, I would advise some caution.

提交回复
热议问题