8

I have the following code in C++ here:

#include <iostream>

int main(int argc, const char * argv[])
{
    goto line2;
line1:
    std::cout << "line 1";
    goto line3;
line2:
    std::cout << "line 2";
    goto line1;
line3:
    std::cout << "line 3";
    goto line4;
line4:
    std::cout << "Hello, World!\n";
    return 0;
}

If I made a larger program of lets say 10,000 lines of code and I decide I am never going to use functions that I write myself, I only use goto statements. I only use global variables. I am slightly insane in terms of best practices, but its for a very specific purpose. The question is, would this be efficient to jump around with goto statements? What if I have 1000 goto labels?

Do the goto statements translate directly into machine code which tells the computer just to JUMP to a different memory address? Is this a lower cost in the machine to jump around like this when compared with the cost to call a function?

I wish to know as I want to write a very efficient program to do some computations and I need to be very efficient without resorting to Assembly/Machine code.


No need to tell me this is a bad idea in terms of maintenance, understandability of code, best practices, I'm very aware of that, I just wish to have an answer to the question. I don't want any debate between whether its good to use function calls or good to use goto.


To clarify the question, I am concerned in this case of using gotos only with a 10,000 line program as to how it would compare with a traditional program using functions. There are multiple ways to compare and contrast between these two programs, for example how would the CPU cache perform. What sort of saving would it give without function calls. Without a call stack, how would this impact on the CPU cache, as CPU caches usually keep the stack close. Would there be therefor a case where it is likely to have a negative performance hit due to the cache not being utilized correctly. What is the actual cost of calling a function as compared to a jump in terms of time efficiency. There's a lot of ways to compare and contrast the two styles of programming in terms of efficiency.

Guy Avraham
  • 3,482
  • 3
  • 38
  • 50
Phil
  • 46,436
  • 33
  • 110
  • 175
  • 1
    Please don't write code this way. Ever. – Spudd86 Jan 07 '13 at 21:20
  • 1
    Why does everyone feel compelled to tell me this?... I've been writing code for over 15 years commercially and started programming at 12 years old, I never write code like this. Except, in this particular case, for my own project. – Phil Jan 08 '13 at 04:57
  • 3
    Its interesting, everyone who sees this question immediately things "oh no, gotos, thats evil" but you have not considered that there are some good reasons for doing this. I am developing a computer language that compiles to C++ code and needs to make use of Goto statements for transfer of execution to different parts of the language. Do you know C++ used to compile to C code then get compiled by a C compiler? Coffeescript compiles to Javascript and gets executed as Javascript. The language I am developing is easier to compile to C++ if I make use of jumps to many different locations in code. – Phil Jan 08 '13 at 05:13
  • Please remember a computer is just a machine which performs instructions, how we make use of that is up to us. – Phil Jan 08 '13 at 05:16
  • I'm not say "gotos that's evil" I'm saying "gotos instead of function calls, that's evil" I've written code that uses gotos, You can't really compile C++ to C with current versions of the language, at least not efficiently. What you are proposing to write is EXACTLY the kind of thing that prompted the "Goto Considered Harmful" paper. – Spudd86 Jan 08 '13 at 15:53
  • Your out of scope of the question, I said "No need to tell me this is a bad idea in terms of maintenance, understandability of code, best practices" AND the question is closed. I won't reply to any further statements about whether gotos are good or bad. – Phil Jan 09 '13 at 02:17
  • @Phil several answers have answered your question, was there some info missing? – Seth Carnegie Jan 09 '13 at 02:23
  • Yes. Do you want to know what that is or are you asking a rhetorical question? – Phil Jan 09 '13 at 02:53
  • The question is closed. So why are you worried about it? – Phil Jan 09 '13 at 02:55
  • @Phil yes I want to know what that is. I am asking because I wrote an answer and voted to reopen. Also if you don't do @ SethCarnegie I don't know you replied. And I believe closed questions still need to have an accepted answer if there is one posted. – Seth Carnegie Jan 09 '13 at 03:48
  • @SethCarnegie Stop pestering people for rep, you're not owed anything and *no* question, open or closed, *needs* an accepted answer. It's *entirely* optional, and *entirely* at the discretion of the person who posted the question – user229044 Jan 09 '13 at 13:50
  • @meagar I'm not, he can do whatever he wants, but I got the feeling he closed it out of frustration. Notice I didn't vote to close. And you're taking _need_ to mean _must have or else..._ when I just mean that it would be nice if it did. I don't have time to explain it to you. – Seth Carnegie Jan 09 '13 at 16:05
  • @SethCarnegie I'm talking "need" to mean what "need" actually means. Words have meanings, and they're pretty well defined. "Need" absolutely doesn't mean "nice to have" in any context or possible use of the word. – user229044 Jan 09 '13 at 16:08
  • @SethCarnegie ... you said "And I believe closed questions still need to have an accepted answer if there is one posted". Need as used here means the same as what meagar said. Ok this is getting crazy, this is a closed question in the backwaters of the internet far away and not even real and your starting to debate the meaning of the word Need. Please go to an english class if you want to debate the meaning of words, thanks. – Phil Jan 10 '13 at 02:33
  • *I only use global variables.* - I thought you were interested in performance. The compiler has to assume that every library function call reads and modifies every global variable, so they have to all be in sync across every call. Local vars (and file-scope `static`) can avoid that if their address hasn't been taken. When a variable does need memory storage, it's cheaper to access relative to the stack pointer than static storage. (Smaller code-size on x86-64, and on most other ISAs, since an absolute address or 32-bit offset isn't needed. Unless you have more than 256B of locals...) – Peter Cordes Nov 02 '22 at 21:27
  • https://godbolt.org/z/G63xEn1r7 shows that compilers can follow these gotos and not actually emit `jmp` instructions for them. (GCC does that even with optimization disabled). Depending on your program structure, the compiler may not be that effective when there are some `if()goto` conditional branches. – Peter Cordes Nov 02 '22 at 21:28

6 Answers6

29

Do the goto statements translate directly into machine code which tells the computer just to JUMP to a different memory address?

Yes.

Is this a lower cost in the machine to jump around like this when compared with the cost to call a function?

Yes.

However, when the compiler sees a function call, it doesn't have to actually generate code to call a function. It can take the guts of the function and stick them right in where the call was, not even a jump. So it could be more efficient to call a function!

Additionally, the smaller your code, the more efficient it will be (generally speaking), since it is more likely to fit in the CPU cache. The compiler can see this, and can determine when a function is small and it's better to inline it, or when it's big and better to separate it and make it a real function, to generate the fastest code (if you have it set to generate the fastest code possible). You can't see this, so you guess and probably guess wrong.

And those are just some of the obvious ones. There are so many other optimisations a compiler can do. Let the compiler decide. it's smarter than you. It's smarter than me. The compiler knows all. Seriously, Cthulhu is probably a compiler.

You said not to, but I'm going to say it: I highly advise you to profile your code before deciding to do this, I can almost guarantee it's not worth your time. The compiler (most of which are near-AI level smart) can probably generate as fast or faster code with regular function calls, not to mention the maintenance aspect.

Seth Carnegie
  • 73,875
  • 22
  • 181
  • 249
  • There are more to optimization than just avoiding function call overload.. Good you mentioned CPU cache thing.. – Krishnabhadra Jan 07 '13 at 05:32
  • @Krishnabhadra yes, I didn't mean to imply that this was all a compiler could do. I will make a note of that. – Seth Carnegie Jan 07 '13 at 05:32
  • 9
    I strongly dislike answers to questions about optimization that say "the compiler is smarter than you". It might be true now, but it doesn't take much to make it false. For the large part, compilers are far from being smart; they're merely fast and persistent. The second paragraph about code size is also misleading; compilers are actually at a heavy disadvantage here relative to a competent programmer with high-level knowledge of the code. But, though I disagree with most of the answer, the fundamental point that inlining is primarily performed on functions is correct. – Veedrac Apr 08 '17 at 21:37
  • A `goto` *can* compile to a `jmp`, but it doesn't have to. In the example in the question, compilers can just put the blocks into the order they're reached by the abstract machine. Even `gcc -O0` does this, although it inserts `nop`s instead of jumps. (https://godbolt.org/z/G63xEn1r7 replaces the `cout<<` with assignment to `volatile int sink` so it's a single instruction with a number right in the instruction.) clang with optimization disabled does use jumps, but of course with optimization they just order the instructions into the right sequence of assignments or calls. – Peter Cordes Nov 02 '22 at 21:20
16

Do the goto statements translate directly into machine code which tells the computer just to JUMP to a different memory address?

Pretty much.

Is this a lower cost in the machine to jump around like this when compared with the cost to call a function?

A function call is going to make a pretty similar jump, but before you can make the jump, you have to set up the new stack frame for the new function, push on parameters according to calling conventions, and at the end set up any return value and unwind. Yes, it's probably faster to not do this.

I am slightly insane

Yes.

James
  • 8,512
  • 1
  • 26
  • 28
4

1) The question is, would this be efficient to jump around with goto statements? What if I have 1000 goto labels?

From your small example with 4 goto labels, where you jump back and forth, no it is not efficient in terms of performance. To avoid overhead in function call mechanism, this method is disabling many other optimization which the compiler will automatically do for you. I am not listing them, but this worth reading.

2) Do the goto statements translate directly into machine code which tells the computer just to JUMP to a different memory address?

YES (As others correctly pointed out)

3) Is this a lower cost in the machine to jump around like this when compared with the cost to call a function?

YES, only if your compiler is pre historic, and doesn't have any optimization mechanism in built. Otherwise NO.

And I am not talking about best practices..

Krishnabhadra
  • 34,169
  • 30
  • 118
  • 167
  • 2
    Please consider 1000 goto statements in 10,000 lines of code. – Phil Jan 07 '13 at 06:00
  • 1
    @Phil again (as meagre pointed out in his comment), no one can answer this question 1)without seeing your 10,000 line code (but I dont want to see it) 2) know about the compiler/machine you running this 3)compiler optimizations you are enabling/disabling.. We can only say this - In normal case, with modern compilers, a programmer don't have to worry much about overhead in function calling mechanisms. Again, that is compiler dependant. – Krishnabhadra Jan 07 '13 at 06:08
  • A `goto` *can* compile to a `jmp`, but it doesn't have to. In the example in the question, compilers can just put the blocks into the order they're reached by the abstract machine. Even `gcc -O0` does this, although it inserts `nop`s instead of jumps. (https://godbolt.org/z/G63xEn1r7 replaces the `cout<<` with assignment to `volatile int sink` so it's a single instruction with a number right in the instruction.) clang with optimization disabled does use jumps, but of course with optimization they just order the instructions into the right sequence of assignments or calls. – Peter Cordes Nov 02 '22 at 21:21
3

Yes, the machine code generated from goto will be a straight JUMP. And this will probably be faster than a function call, because nothing has to be done to the stack (although a call without any variables to pass will be optimized in such a way that it might be just as fast).

And God help you when something doesn't work with this code. Or when someone else has to maintain it.

DWright
  • 9,258
  • 4
  • 36
  • 53
  • 6
    **Or when someone else has to maintain it**.. Ouch.. – Krishnabhadra Jan 07 '13 at 05:24
  • 2
    This is a gross over-simplification. Compilers do this thing called optimization. I would wager heavily that a compiler will produce more optimal code when functions are used, vs 10,000 lines of code containing 1000 goto's. – user229044 Jan 07 '13 at 05:26
  • Yes meager, your comment is the answer to the question, especially since performance optimization is OP's very concern... – Krishnabhadra Jan 07 '13 at 05:28
  • 2
    If you look again at what I said, you'll see that I was trying to be careful not to oversimplify what the optimizer will or won't achieve. – DWright Jan 07 '13 at 05:28
  • 1
    @krishnabhadra. Once this becomes a non-trivial piece of code, it'll probably be minimally faster than with function calls. A non-trivial piece of code will have enough variables involved that the compiler will not optimize away or inline all function calls. The stack will be occacionally pushed or popped as a result. this will not be faster. Doesn't mean that the gotos are better. In fact the opposite is true. – DWright Jan 07 '13 at 05:30
  • 1
    +1 There are a lot of people commenting who seem to know nothing about code optimization or how compilers handle gotos. – Jim Balter Jan 07 '13 at 06:52
2

hard to answer your query precisely, it depends on complexity of your program and use of goto statements within.

goto statement is equivalent to unconditional jump instruction (e.g. jmp ). The scope of goto will be within the file.

Ritchie suggest that avoid using goto statement, and if still want to/have to use goto statement then use it in top-down approach, Dont use it in bottom-up approach.

Well these are text book details.

Practically you should be very sure where to use goto statement and after goto jump where your program flow will be, otherwise as you mentioned with 1000 goto statements it will be difficult for you also to decide the program flow, forget about others. So further improvement in your program will be very very difficult.

There are plenty of other facilities such as looping, conditional statements, break and continue statements, functions etc to help you avoid such problems.

Hope it helps.....

Kinjal Patel
  • 405
  • 2
  • 7
  • 2
    the query ----> Do the goto statements translate directly into machine code which tells the computer just to JUMP to a different memory address? the repy ----> goto statement is equivalent to unconditional jump instruction (e.g. jmp ). The scope of goto will be within the file. – Kinjal Patel Jan 07 '13 at 05:40
  • 2
    the query ------> The question is, would this be efficient to jump around with goto statements? What if I have 1000 goto labels? the answer -------> Practically you should be very sure where to use goto statement and after goto jump where your program flow will be, otherwise as you mentioned with 1000 goto statements it will be difficult for you also to decide the program flow, forget about others. So further improvement in your program will be very very difficult. – Kinjal Patel Jan 07 '13 at 05:42
0

In short, 'GoTo' statements can be efficient, but that is really how they are used. According to Herbert Schildt (C++ from the GROUND UP), "There are no programming situations that require the use of the goto statement -- it is not an item necessary for making the language complete." Ultimately, the primary reason for many programmers disliking the statement is that goto statements tend to clutter your code and/or make it very difficult to read because, as per the name, gotos can jump from place to place. With that being said, there are times where a goto statement can reduce clutter as well as make code more efficient, but that is totally dependent upon how you use them and the context that they are used in. Personally, I would recommend using function calls, as oppose to several goto statements; others may disagree.

David Venegoni
  • 508
  • 3
  • 13