Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Examples of good gotos in C or C++ [closed]

Tags:

c++

c

goto

People also ask

What is goto give an example?

The use of goto statement may lead to code that is buggy and hard to follow. For example, one: for (i = 0; i < number; ++i) { test += i; goto two; } two: if (test > 5) { goto three; } ... .. ... Also, the goto statement allows you to do bad stuff such as jump out of the scope.

Is goto good in C?

NOTE − Use of goto statement is highly discouraged in any programming language because it makes difficult to trace the control flow of a program, making the program hard to understand and hard to modify. Any program that uses a goto can be rewritten to avoid them.

What is the use of goto and labels in C?

goto is a jumping statement in c language, which transfer the program's control from one statement to another statement (where label is defined). goto can transfer the program's within the same block and there must a label, where you want to transfer program's control.


Heres one trick I've heard of people using. I've never seen it in the wild though. And it only applies to C because C++ has RAII to do this more idiomatically.

void foo()
{
    if (!doA())
        goto exit;
    if (!doB())
        goto cleanupA;
    if (!doC())
        goto cleanupB;

    /* everything has succeeded */
    return;

cleanupB:
    undoB();
cleanupA:
    undoA();
exit:
    return;
}

The classic need for GOTO in C is as follows

for ...
  for ...
    if(breakout_condition) 
      goto final;

final:

There is no straightforward way to break out of nested loops without a goto.


Here's my non-silly example, (from Stevens APITUE) for Unix system calls which may be interrupted by a signal.

restart:
    if (system_call() == -1) {
        if (errno == EINTR) goto restart;

        // handle real errors
    }

The alternative is a degenerate loop. This version reads like English "if the system call was interrupted by a signal, restart it".


If Duff's device doesn't need a goto, then neither should you! ;)

void dsend(int count) {
    int n;
    if (!count) return;
    n = (count + 7) / 8;
    switch (count % 8) {
      case 0: do { puts("case 0");
      case 7:      puts("case 7");
      case 6:      puts("case 6");
      case 5:      puts("case 5");
      case 4:      puts("case 4");
      case 3:      puts("case 3");
      case 2:      puts("case 2");
      case 1:      puts("case 1");
                 } while (--n > 0);
    }
}

code above from Wikipedia entry.


Knuth has written a paper "Structured programming with GOTO statements", you can get it e.g. from here. You'll find many examples there.


Very common.

do_stuff(thingy) {
    lock(thingy);

    foo;
    if (foo failed) {
        status = -EFOO;
        goto OUT;
    }

    bar;
    if (bar failed) {
        status = -EBAR;
        goto OUT;
    }

    do_stuff_to(thingy);

OUT:
    unlock(thingy);
    return status;
}

The only case I ever use goto is for jumping forwards, usually out of blocks, and never into blocks. This avoids abuse of do{}while(0) and other constructs which increase nesting, while still maintaining readable, structured code.


I have nothing against gotos in general, but I can think of several reasons why you wouldn't want to use them for a loop like you mentioned:

  • It does not limit scope hence any temp variables you use inside won't be freed until later.
  • It does not limit scope hence it could lead to bugs.
  • It does not limit scope hence you cannot re-use the same variable names later in future code in the same scope.
  • It does not limit scope hence you have the chance of skipping over a variable declaration.
  • People are not accustomed to it and it will make your code harder to read.
  • Nested loops of this type can lead to spaghetti code, normals loops will not lead to spaghetti code.

Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!