Problems that can arise from using a GOTO statemen

2019-08-26 14:02发布

问题:

Is there any harm for using a GOTO statement to jump down only ? Or are we totally safe ?

What I mean by that is think this as my code,

Some code ...
...

GOTO whereToJump

Some code ...
...

whereToJump: 

Some code ...

When whereToJump point is always below the GOTO statement, is there any security issues?

回答1:

This is subject of one of the most famous computer science papers. Go To Statement Considered Harmful by Dijkstra. It essentially states that noone ever needs goto (I know there are a few exceptions as always).

It is 1968 but still very readable today.



回答2:

It makes sense that only downward jumps makes for much less potential for spaghetti code. ( in my experience, 75% of the headache in debugging legacy GOTO-based code comes from that case when upward gotos result in chaotic looping )

However, given that you are only using downward jumps, it should be very easy to convert to non-goto based code. I'm not sure how much of an improve your gotos would provide.



回答3:

In any more complicated example, surely if you can decide to use the GOTO only to jump forward in the same scope, you could use an if statement. (If it's not in the same scope, it's not really "just jumping forward", is it?)

(And, of course, if your real code is not more complicated than that, you could just get rid of that second block of "Some code...")



回答4:

The cardinal reason why GOTOs should be avoided these days is that programmers in general are not used to GOTOs any more (which is a good thing). So if you write code that makes extensive use of GOTOs, chances are your fellow programmers will have difficulty understanding and extending it.

Worse, a GOTO here and there may lead to Broken Window Syndrome as colleagues begin to use more and more GOTOs until you're left with a big bowl of spaghetti.

xkcd puts it best...



回答5:

I use goto statements when it is needed to jumb to a code block from many locations downward. Usually without goto statement, this may require to write another function (so that the code block above is not repeated in the first function) and call inside the first. goto is no less efficient than if or switch statements since it also utilizes one of the jumb statements (jz, jnz, etc) which are used by if, switch, etc.



回答6:

goto does not make the code less safe independent of which way you jump.

You structure your code any way you like. It is your code that decides if the code is good/bad. goto maybe appropriate in some cases (no I can's show an example :-) )

The problem with goto is that it may hide the flow of execution in the program and make the code confusing. But if you create easy to read/maintain code then that is not a problem.



回答7:

Well, there's really no problem. That code is equivalent to:

Some code ...
...

if (false)
{
Some code ...
...
}

Some code ...

That said, I wouldn't do it. Good use cases for goto are really rare, and other flow control constructs are more idiomatic in C#.



回答8:

With this comment I'm not encouraging the use of GOTOs, but just to make a point that in some very specific case it can be useful. So far in practice I have not seen any code that uses goto statements to jump around either upward or downward, but there is one specific use case where I find goto to be more readable. Here is an example of a code where I think goto makes more sense.

void fun_test ()
{
    .code..
    allocate dynamic memory.
    acquire_lock();

    //do some action, call api. 
    if (some error) {
       print error;
       free memory;
       unlock();
       return FAIL;
    } else {
        // some code.
    }

    if (some_other error) {
        print error;
        free memory;
        unlock();
        return FAIL;
   }
   :
   :
   // more error condition checks.
   :
   return SUCCESS

}

void fun_test_withgoto ()
{
    error_code rc = SUCCESS;
   .code..
   allocate dynamic memory.
   acquire_lock();

   //do some action, call api.
   if (some error) {
       rc = <Failure id>;
       goto function_cleanup;
   } else {
      // some code.
   }

   if (some_other error) {
      rc = <failure id>;
      goto function_cleanup;      
   }
:
:
// more error conditions.
:

function_cleanup:
    if (rc == SUCCESS) {
        print "Success..";
    } else {
        print "Error : <failure id>";
    }
    free_memory();
    unlock();
    return(rc);
}


标签: c# goto