GOTO, why are you adverse to using it

Started by
74 comments, last by SmkViper 9 years, 7 months ago

int do_work(int stuff)
{
int res1 = 0, res2 = 0, res3 = 0;
int success = 0;

res1 = acquire_one_resource(stuff);
if (!res1) goto cleanup;

res2 = acquire_another_resource(stuff);
if (!res2) goto cleanup;

res3 = acquire_more_resources(stuff);
if (!res3) goto cleanup;

/* etc. */

success = 1;

cleanup:
/* here the only requirement is that the cleanup process
* ignores unacquired resources, perhaps with some minor
* logic if you have pointers to resources (unusual) */

free_resource(res3);
free_resource(res2); // would you look at that, all the cleanup code
free_resource(res1); // in one single spot, no code duplication
return success;
}

Considering a GOTO can invalidate reused code or functions, and forces a reader who did not write it (or forgot about it) to search all gotos of the label that refernce it where code redirects to the label. Like "oh there are only three gotos of the label good- oh- they happen to be luckily close and does not break the local scope, good, oh they redirect only from 3 different conditions, oh, hopefully all variations in runtime will work, oh hopefully cleanup is dull-clean safe in case second resource fail with third not allocated, oh...."

I like that if a function encounters an error, it correctly hands back the runtime to the calling scope back up, without this possible ot not viable, some goto will not help as well. (that is why try catch was implemented, so even not correctly returning functions will not couse upper scope to fall, and can prepare walking back to upper upper scope)

Many languages does not implement goto (porting and machine expresebility of instruction gone), and some does but in different way.

The talk of using goto as an optimization to save clock cycles is a bit ironic,

So much this Hodgeman. If we omit invalidating codeflow production at the moment of using it, there is no comploted situation where goto would outperform continue, return or break alternative of code. And the last argument to support goto, making code more readable at some situation, is self negating, since it involves runtime danger combined with need to analyze the label around entire project.

You can use goto only in your own project, that only you are writing, if you happen to remember all you have ever written in sufficient details.

Then of course there's the fact that when it comes to being in the workforce, you'll be a lot more likely to get a job and keep it if you don't use them.

I would stress this.

Advertisement


Let's not forget that goto fail; happened.

Wow I noticed that my device is vulnerable and I wasn't aware of it. I deliberately avoid ios 7 as I dislike it very much so is there no patch for 6.1.2? I kinda hate how apple always forces the very last os on you.

On another note, I don't understand how the bug works. the second goto fail: does skip an important signature check but... executing it and the signature not being valid also branches to fail: it seems this code always goes to fail, no matter what.

EDIT

I think it's err's value that matters. Ignore my post.

On another note, I don't understand how the bug works. the second goto fail: does skip an important signature check but... executing it and the signature not being valid also branches to fail: it seems this code always goes to fail, no matter what.

EDIT

I think it's err's value that matters. Ignore my post.

The value of err, as set from the previous call, is zero. Thus the second goto fail; simply goes straight to fail and returns 0, which is "no error occurred".

In time the project grows, the ignorance of its devs it shows, with many a convoluted function, it plunges into deep compunction, the price of failure is high, Washu's mirth is nigh.

People should never discuss "goto" without first acknowleging that there are 2 different types of goto ... (that are as different as for loops and foreach loops).

The "goto" that exists in languages like (the old line numbered version of) BASIC, and a high proportion of early langauges is the unscoped goto. It is the all-powerful, context free, danerous and evil goto. This goto has the power to transfer execution from a line in any method in any file, to a line in any method in any other file. This goto is "dangerous" in every sense of the word ... because it has no limits.

Just like a military grade weapon it is powerful, and appropriate at the right time (perhaps if you are writing an optimizing compiler or some such, or working in a langauge that is more efficient when using unstructured paradigms). And because this goto is so powerful - it takes rules and training to use it without hurting people. But this goto has been removed from nearly all modern langauges ... because its power CANNOT be used safely if you cannot trust every developer to always follow whatever rules you invent to guide its use ... and its use would deny the ability of any but the most awesome non-JIT compiler from ever being able to guarantee ANYTHING about ANYTHING ... it couldn't know how to clean up stack frames, free resources, do garbage collection, etc ... because the "jump somewhere, anywhere, whenever" feature would block any logical solutions to any but the simplest programs. ... "tail call optimization" is kinda like a goto ... but this leads to my point.

The universal unlimited goto was REMOVED and REPLACED with other, more structured (aka limited) contructs ... that have been proven to be able to acomplish all necessary goals ... albiet without ideal efficiency in some cases ... with less danger and more guarantees.

The current GOTO in almost all currently used languages (except ASM) is a different goto entirely ... it cannot see or reference any labels outside of its own method/scope ... therefore it is just simple, weak, powerless syntactic suger for doing multiple breaks, etc ... if this goto had been named something else (perhaps "escape" or something) people would realize that it isn't the same thing written about over the years ... it is mathematically similar in structured programming consequences as the practice of using more than 1 return in a method (which violates structured programmings rules ... but since it is limited in maximum scope to a function, noone cares ... cause any real programmer can handle seeing it in any function that isn't so large it shouldn't exist anyway).

So just remember ... your goto in whatever language you currently use, probably isn't really a goto at all ... its just a slightly more powerful flow construct than a break statement, with a really bad reputation ...

but also remebmer, when they removed the POWER of the goto ... they also removed the REASON for a goto ... there is no longer any case where the current goto cannot be restructured as some other layout of code, that yields IDENTICAL performance and machine code in every way.

So goto is no longer harmfull, it is just pointless.

Why don't people quoting these multiple resource acquisition examples just do this:


bool do_acquire(Res &r1, Res &r2, Res &r3)
{
    if(!acquireRes(r1)) return false;
    if(!acquireRes(r2)) return false;
    if(!acquireRes(r3)) return false;

    return true;
}

void acquire()
{
    Res r1, r2, r3;

    if(!do_acquire(r1, r2, r3))
    {
        clean_up_if_allocated(r3);
        clean_up_if_allocated(r2);
        clean_up_if_allocated(r1);
    }
}
I'm deliberately simplifying and avoiding the use of RAII to make it as close to the examples posted. What possible advantage does goto give you over this equivalent approach?

Why don't people quoting these multiple resource acquisition examples just do this:






bool do_acquire(Res &r1, Res &r2, Res &r3)
{
    if(!acquireRes(r1)) return false;
    if(!acquireRes(r2)) return false;
    if(!acquireRes(r3)) return false;

    return true;
}

void acquire()
{
    Res r1, r2, r3;

    if(!do_acquire(r1, r2, r3))
    {
        clean_up_if_allocated(r3);
        clean_up_if_allocated(r2);
        clean_up_if_allocated(r1);
    }
}
I'm deliberately simplifying and avoiding the use of RAII to make it as close to the examples posted. What possible advantage does goto give you over this equivalent approach?


Every possible use of goto can be done with a different (and probably more-readable/understandable) control-flow structure in the language (at least in C++).

Some people just really love their gotos.

This topic is closed to new replies.

Advertisement