Is it possible to store the address of a label in a variable and use goto to jump to it?

前端 未结 14 1600
执念已碎
执念已碎 2020-12-04 09:35

I know everyone hates gotos. In my code, for reasons I have considered and am comfortable with, they provide an effective solution (ie I\'m not looking for \"don\'t do that\

相关标签:
14条回答
  • 2020-12-04 10:24

    You can do something similar with setjmp/longjmp.

    int main (void)
    {
        jmp_buf buf;
        int i=1;
    
        // this acts sort of like a dynamic label
        setjmp(buf);
    
        if( i-- )
            // and this effectively does a goto to the dynamic label
            longjmp(buf, 1);
    
        return 0;
    }
    
    0 讨论(0)
  • 2020-12-04 10:28

    According to the C99 standard, § 6.8.6, the syntax for a goto is:

        goto identifier ;
    

    So, even if you could take the address of a label, you couldn't use it with goto.

    You could combine a goto with a switch, which is like a computed goto, for a similar effect:

    int foo() {
        static int i=0;
        return i++;
    }
    
    int main(void) {
        enum {
            skip=-1,
            run,
            jump,
            scamper
        } label = skip; 
    
    #define STATE(lbl) case lbl: puts(#lbl); break
        computeGoto:
        switch (label) {
        case skip: break;
            STATE(run);
            STATE(jump);
            STATE(scamper);
        default:
            printf("Unknown state: %d\n", label);
            exit(0);
        }
    #undef STATE
        label = foo();
        goto computeGoto;
    }
    

    If you use this for anything other than an obfuscated C contest, I will hunt you down and hurt you.

    0 讨论(0)
  • 2020-12-04 10:28

    The only officially supported thing that you can do with a label in C is goto it. As you've noticed, you can't take the address of it or store it in a variable or anything else. So instead of saying "don't do that", I'm going to say "you can't do that".

    Looks like you will have to find a different solution. Perhaps assembly language, if this is performance-critical?

    0 讨论(0)
  • 2020-12-04 10:29

    The C and C++ standards do not support this feature. However, the GNU Compiler Collection (GCC) includes a non-standard extension for doing this as described in this article. Essentially, they have added a special operator "&&" that reports the address of the label as type "void*". See the article for details.

    P.S. In other words, just use "&&" instead of "&" in your example, and it will work on GCC.
    P.P.S. I know you don't want me to say it, but I'll say it anyway,... DON'T DO THAT!!!

    0 讨论(0)
  • 2020-12-04 10:29

    Use function pointers and a while loop. Don't make a piece of code someone else will have to regret fixing for you.

    I presume you're trying to change the address of the label somehow externally. Function pointers will work.

    0 讨论(0)
  • 2020-12-04 10:33

    According to this thread, label points are not a standard, so whether they work or not would depend on the compiler you're using.

    0 讨论(0)
提交回复
热议问题