27

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

int main() { // .... REACH: // .... } void function() { goto REACH; } 
10
  • 4
    You should not be using goto xkcd.com/292 Commented Jun 28, 2013 at 4:32
  • 2
    Try setjmp instead. Commented Jun 28, 2013 at 4:34
  • 5
    Question: Why on earth do you want to do this? Surely there are better ways. Commented Jun 28, 2013 at 5:06
  • 20
    @Ben don't generalize. goto is not always considered as a bad practice. goto is very useful in C when you need to gracefully cleanup and exit from function. You can see many goto instructions in Linux kernel and many other huge projects. Commented Aug 26, 2016 at 11:18
  • 8
    Also it's good for breaking out of multiple nested loops. Commented Jun 30, 2017 at 10:06

4 Answers 4

29

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.

Sign up to request clarification or add additional context in comments.

Comments

25

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.

Comments

3

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

1 Comment

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

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

2 Comments

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. "
this answer should not have any upvotes, it is UB

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.