esote
esote

Reputation: 851

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.

Upvotes: 5

Views: 4383

Answers (5)

rustyx
rustyx

Reputation: 85341

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;
}

Upvotes: 2

rahnema1
rahnema1

Reputation: 15837

this is a simple macro solution:

#define CALL_VARIALBLE(name) goto name;

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

    return 0;
}

Upvotes: 2

Cheers and hth. - Alf
Cheers and hth. - Alf

Reputation: 145269

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 );
    }
}

Upvotes: 4

Jesper Juhl
Jesper Juhl

Reputation: 31465

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..

Upvotes: 3

Qaz
Qaz

Reputation: 61910

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.

Upvotes: 14

Related Questions