简体   繁体   中英

C++ Goto variable

Is there a way to call a goto statement using a variable in the place of a label name?

I'm looking for something similar to this (this doesn't work for me):

// std::string or some other type that could represent a label
void callVariable(std::string name){
    goto name;
}

int main(){
    first:
    std::cout << "Hi";
    callVariable(first);

    return 0;
}

I am not actually using this, I am more interested in learning.

Yes and no. There's no such standard language feature, but it is a compiler extension in at least GCC:

int main() {
    void* label;

    first:
    std::cout << "Hi";
    label = &&first;
    goto *label;
}

That said, I'd have to think hard for a use case where this is better than any standard alternatives.

Short answer: no.

Long answer: no. And why would you want this? Just stop using goto already.

Maybe (just guessing) what you want is a std::function or a switch instead..

You ask:

Is there a way to call a goto statement using a variable in the place of a label name?

Yes, the feature in C++ that provides that effect is called switch . It doesn't syntactically involve the word goto . But it jumps to a label specified by a variable, and so, with it you can emulate all kinds of dirty goto -based code, including early Basic's on ... goto ... .


Your hypothetical example

int main(){
    first:
    std::cout << "Hi";
    callVariable(first);

    return 0;
}

… looks like this in real C++:

#define CALL_VARIABLE( where ) next_jump = where; break;

auto main()
    -> int
{
    enum Label {first, second, third};
    Label next_jump = first;
    for( ;; ) switch( next_jump )
    {
    case first:
        std::cout << "Hi";
        CALL_VARIABLE( first );
    }
}

this is a simple macro solution:

#define CALL_VARIALBLE(name) goto name;

int main(){
    first:
    std::cout << "Hi";
    CALL_VARIALBLE(first);

    return 0;
}

You can't goto a dynamic location.

But you can have a look at POSIX setjmp / longjmp , which can be used to jump to a predefined location in your application. MSVC also supports it.

#include <stdio.h>
#include <setjmp.h>

static jmp_buf buf;

void second(void) {
    printf("second\n");         // prints
    longjmp(buf,1);             // jumps back to where setjmp was called - making setjmp now return 1
}

void first(void) {
    second();
    printf("first\n");          // does not print
}

int main() {   
    if (!setjmp(buf))
        first();                // when executed, setjmp returned 0
    else                        // when longjmp jumps back, setjmp returns 1
        printf("main\n");       // prints

    return 0;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM