22

How can I use goto across different functions? For example:

int main() {
    // ....
    REACH:
    // ....
}
    
void function() {
    goto REACH;
}
OverShifted
  • 457
  • 1
  • 7
  • 17
Bhushanam Bhargav
  • 301
  • 1
  • 4
  • 10
  • 3
    You should not be using goto http://xkcd.com/292/ – Fantastic Mr Fox Jun 28 '13 at 04:32
  • 2
    Try `setjmp` instead. – UltimaWeapon Jun 28 '13 at 04:34
  • 5
    Question: Why on earth do you want to do this? Surely there are better ways. – michaelb958--GoFundMonica Jun 28 '13 at 05:06
  • 1
    Not answering your question of course, but instead you could make the goto part it's own functions which you call from both main and function. No reason to clutter you code with gotos. – martiert Jun 28 '13 at 05:30
  • You should probably have a look at this answer: – thegeeklife Apr 08 '15 at 20:42
  • 1
    @michaelb958 He's probably implementing a continuation. – Navin Jul 26 '15 at 03:39
  • 15
    @Ben don't generalize. `goto` is *not* always considered as a bad practice. `goto` is [very useful](http://programmers.stackexchange.com/questions/154974/is-this-a-decent-use-case-for-goto-in-c) in [C](https://en.wikibooks.org/wiki/C_Programming) when you need to gracefully cleanup and exit from function. You can see many `goto` instructions in Linux kernel and many other huge projects. – patryk.beza Aug 26 '16 at 11:18
  • 7
    Also it's good for breaking out of multiple nested loops. – HolyBlackCat Jun 30 '17 at 10:06
  • 1
    You probably should limit this question to either C or C++. If you are using C++, standard exception handling might provide a solution. It is not available in C and you don't show enough of `main` to say for sure. – John Jun 15 '19 at 12:12
  • This is exactly the problem with functions. To all the people who say, "Why would you ever need this? You're doing something wrong. Do it differently." Screw off. There are very legitimate cases where you need this. Also sometimes functions are just a replacement for redundant or iterative code and that code ends up needing to goto. – Andrew Jun 15 '21 at 04:40

4 Answers4

24

You can't in Standard C++. From $6.6.4/1 of the C++ Language Standard

The goto statement unconditionally transfers control to the statement labeled by the identifier. The identifier shall be a label (6.1) located in the current function.

...or in Standard C. From $6.8.6.1/1 of the C Language Standard

The identifier in a goto statement shall name a label located somewhere in the enclosing function. A goto statement shall not jump from outside the scope of an identifier having a variably modified type to inside the scope of that identifier.

Captain Obvlious
  • 19,754
  • 5
  • 44
  • 74
23

You can't in Standard C; labels are local to a single function.

The nearest standard equivalent is the setjmp() and longjmp() pair of functions.

GCC has extensions to support labels more generally.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
4

For gcc:

#include <iostream>

void func(void* target){
    std::cout << "func" <<std::endl;
    goto *target;
}


int main() {
    void* target;
    auto flag = true;
l:
    std::cout << "label" <<std::endl;
    target = &&l;
    if (flag) {
        flag = false;
        func(target);
  }
}

Note that this can be an undefined behavior

Andrio Skur
  • 755
  • 9
  • 22
  • 7
    https://gcc.gnu.org/onlinedocs/gcc-3.2/gcc/Labels-as-Values.html: "You may not use this mechanism to jump to code in a different function. If you do that, totally unpredictable things will happen. " – Petr Skocik Jun 15 '19 at 12:09
  • 1
    this answer should not have any upvotes, it is UB – pm100 Feb 20 '22 at 18:31
2

You can't. Think of this. There is a function A which is recursively calling another function B which in turn is calling A. Now, suppose that you put a goto statement from A to B. The question now becomes which instance of A do you want to go to which is undefined. Also, if no previous instance of A is defined, you have a bigger problem of no initialized variables in the function that are present before the label.

#include "bits/stdc++.h"
int i=0;
A(){
run:
    B();
}
B(){
if(i==10)
    goto run;
i++;
A();
}
Rishabh Jain
  • 131
  • 5
  • 1
    Good point. This is exactly the problem with functions. We have no control over the stack in this sense. We should be able to revert a part of it and/or store certain places in the stack which we want to revert to. There is `setjmp()` and `longjmp()`, but these are slow and bring trouble when it comes to "stack" variables. The problem is for sake of convenience we've given up very useful functionality. The whole paradigm is flawed. – Andrew Jun 15 '21 at 04:48