Live data from Hacker News

Goto (2007)

beej.us

91–100 of 207 posts

Re: Goto (2007)

#91
post #71
post #49

I like the presentation of the three nexted loops. Maybe "break;" should become a shortform for a generalized "break(1);" (= break one level) if we want to avoid using goto. Perhaps this can be implemented by combining a macro with setjmmp() and longjmp() from the standard C library, without requiring a compiler change.

Yep, some goto uses were ostracized without ever providing the alternative. In other languages breaking numerous loops is done by naming the one you want to control: outer: for () { for () { for () { break outer;

This is much more confusing to me than just using a goto. From your example, it's not immediately clear at all to me if you're breaking out of outer, or if you're breaking TO outer. You can figure it out with this simple example, but it's way more confusing than it needs to be. And importantly: way more confusing than just using goto.

Given that break and continue are just gussied up gotos anyway, just put the label where you wanna go and goto it. I think it's one of the few perfectly valid uses goto.

Re: Goto (2007)

#92

> Multi-level Cleanup Used all the time a decade or so ago when writing code that made heavy use of Apple's CoreFoundation. CF could return nil (failure) for many operations, and memory management at that time was left up to the programmer. // Not real code, approximated from recollection bool createNestedCFThing () { CFDictionary *thing = nil; CFArray *arrayObj = nil; CFString *string1 = nil; CFString *string0 = nil…

Manual memory management is bad but you can't escape it in C so `goto` is mildly useful there for that purpose. In all other languages you get better ergonomics.

* In Rust you wouldn't need any of that boilerplate because lifetime is automatically managed (& Rust has Objc bindings).

* If you turn on ARC & use the NS types you don't need this (they map to the same thing with no overhead for these primitives, so there's no good reason not to do this unless you are just being masochistic).

* In ObjC++ you should still use ARC. But if you felt masochistic, you could do:

    auto string0 = unique_ptr(CFCreateString("Hello"));
    auto string1 = unique_ptr(CFCreateString("World"));
    auto arrayObj = unique_ptr(CFCreateMutableArray(kCFAllocatorDefault, 2, kCFTypeArrayCallBacks, kCFTypeDictionaryKeyCallBacks, ));
    auto thing = unique_ptr(CFCreateMutableDictionary(kCFAllocatorDefault, 1, kCFTypeDictionaryKeyCallBacks, kCFTypeDictionaryValueCallBacks));
    if (!arrayObj || !string0 || !string1 || !thing) {
      return nil;
    }
    if (!CFArrayAppendValue(arrayObj.get(), string0.get()) || !CFArrayAppendValue(arrayObj.get(), string1.get())) {
      return nil;
    }
    if (!CFDictionaryInsertObjectWithKey(thing.get(), arrayObj.get(), "somekey")) {
      return nil;
    }
    return thing.release()
In C++ you could also use scope guards if you didn't like the `unique_ptr` stuff (not part of the stdlib yet, but it's not hard to roll your own).

The point I'm trying to make is that there are much cleaner ways of obtaining that result in whatever language you choose. If you do that, maybe you too won't be responsible for a goto fail security flaw [1].

EDIT: BTW. This advise isn't out of the blue. This was 100% a strong culture even within Apple 5 years ago. If you're concerned about performance of ARC, consider that Apple dogfoods it internally for nearly every part of the OS. The only pieces it's not used are for large historical codebases where the migration cost is a factor. Performance of ARC vs manual just isn't something anyone looks at. For the historical codebases usually one would use the ObjC++ approach instead.

[1] https://nakedsecurity.sophos.com/2014/02/24/anatomy-of-a-got...

Re: Goto (2007)

#93
post #4

Coming from assembly language, I always found the anti-goto sentiment rather cute. A beautiful restriction, but ultimately arbitrary. Like writing poetry. Or those novels that do not ever use the letter "e". Why would an otherwise sane person write code with "rep" and without ever using "jmp"?

> Coming from assembly language, I always found the anti-goto sentiment rather cute. A beautiful restriction, but ultimately arbitrary. Like writing poetry. Or those novels that do not ever use the letter "e". Why would an otherwise sane person write code with "rep" and without ever using "jmp"? There is no need to use GOTO when a language has functions/procedures and exceptions. Of course it makes sense in Assembly…

> There is no need to use GOTO when a language has functions/procedures and exceptions.

The usual example of when goto saves more trouble than it causes is breaking out of a nested loop early. You can avoid goto in that scenario with a sufficient number of flags, but flag-heavy code tends to be harder to read than a couple apposite gotos. Even better is Perl-style named blocks, though.

Re: Goto (2007)

#94
post #76

Earlier quoted context omitted.

MISRA doesn't ban it, that rule is only Advisory which pretty much means you can ignore it. Rules 15.2 and 15.3 (Required) define how you can use goto if you decide to use it. Rule 15.2 The goto statement shall jump to a label declared later in the same function (forward gotos only) Rule 15.3 Any label referenced by a goto statement shall be declared in the same block, or in any block enclosing the goto statement (ca…

I'm familiar with MISRA (embedded dev), I only wanted to point out that the MISRA rules in no way justifies a blanket ban on gotos. The ban (in the case of C, anyway) is almost always the result of someone's completely subjective opinion that gotos are bad.

A customer put a blanket ban on goto because they decided to require MISRA 15.1 and want(need) to be compliant as well as having their own interpretation of MISRA. They also put a blanket ban on multiple returns (15.5).

While it is true MISRA does not intend a blanket ban on these (and a blanket ban is contrary to the rationale for these rules), it often leads to a blanket ban and when these two in particular happen together it leads to awful code. I've seen this from multiple customers in different industries.

Re: Goto (2007)

#95
post #61

Earlier quoted context omitted.

> Coming from assembly language, I always found the anti-goto sentiment rather cute. A beautiful restriction, but ultimately arbitrary. Like writing poetry. Or those novels that do not ever use the letter "e". Why would an otherwise sane person write code with "rep" and without ever using "jmp"? There is no need to use GOTO when a language has functions/procedures and exceptions. Of course it makes sense in Assembly…

> There is no need to use GOTO when a language has functions/procedures and exceptions. ... and defer

> and defer

Which “defer”? The go panic/defer pair is, while structured differently, functionally equivalent to exceptions.

Re: Goto (2007)

#96
post #4

Coming from assembly language, I always found the anti-goto sentiment rather cute. A beautiful restriction, but ultimately arbitrary. Like writing poetry. Or those novels that do not ever use the letter "e". Why would an otherwise sane person write code with "rep" and without ever using "jmp"?

Bringing it more generally, it's a powerful tool that's simple to use.

This means it is ripe for abuse by amateurs and fools and from that comes its reputation.

It's a shame that dogmas are developed against the use of such things instead of creating a culture of appropriate use.

You see it against say php, jquery, and even gof design patterns these days.

It's bullshit. Just because some buffoons do stupid things with something powerful it doesn't mean all people that use it are buffoons

Re: Goto (2007)

#97

Earlier quoted context omitted.

> A beautiful restriction, but ultimately arbitrary. Like writing poetry. This assessment cuts pretty close to the gist of (my reading of) Dijkstra's famous paper that kicked off the anti-goto sentiment, once you take some time to digest the entirety of the paper and consider the context in which it was being written. I'd also like to throw out there, though, that the "go to" statement he describes is a "go to" state…

Right. He was criticizing the version where one subroutine might jump into the middle of another subroutine. That sort of thing can make safely modifying the second subroutine require knowing if any of its labels are used elsewhere in the program. It is basically impossible to reason locally when developing like that, unless you first verify that the only uses are local. (Or have applied strict coding standards such…

There's setjmp() and longjmp()to do that :)

Re: Goto (2007)

#98

There are a few situations like this, where a bad practice is in a specific case good enough: Using goto to bail out multiple levels, using SHA-1 as a non-secure hash, ... The problem is these things waste social bandwith: Someone reading your code for maintenance or code review will first declare the code bad (GOTO is ugly! SHA-1 is insecure!), then you have to signal to them that it's actually OK in this case, then…

> The problem is these things waste social bandwith: Someone reading your code for maintenance or code review will first declare the code bad (GOTO is ugly! SHA-1 is insecure!), then you have to signal to them that it's actually OK in this case, then they have to convince themselves that actually it is OK.

This is something that changes over time as the new convention gets reinforced. If you don't push back it will never change. In other words, the conventional way of doing things needs to be spread organically.

A lot of conventions work that way. Since I'm in Web Dev, one example I can think of is the change from fat models to service objects in MVC. Fat models used to be seen as the way of doing things. But, now that many of us have encountered giant balls of mud caused by this pattern, we've adapted a new convention and moved on.

If you can provide good uses of goto in the wild and push back against opposition the same thing will happen, in my opinion. Eventually the opposition goes away.

Re: Goto (2007)

#99
Probably coming too late to the discussion, but commenting anyway...

The issue I think is that people today read "GOTO Considered Harmful" without really understanding the world at the time.

Other than simple integer FOR loops, basically all control-flow in the FORTRAN of those days was accomplished with GOTO -- and to numbered lines, not labels. Things we take for granted in all languages today like { code blocks } didn't exist.

Indeed the first thing you do when you try to understand code of that era is to print it out, get your markers out, and start drawing arrows all over the green-bar paper so you can start to make some sense of where control flow is going.

In that world, yes, GOTO was a big problem and its use was rightly replaced with the structured control flow that we all use today. But that world has also been nearly gone for 30 years now. It's completely unrelated to using a C "goto" statement with a well-chosen label name in order to accomplish some otherwise-awkward control flow.

On projects I've worked on I tend to develop a reputation for heavy goto use and I do so unapologetically. Sometimes it honestly is the cleanest way to implement something and I don't think it should be feared one bit.

Just because it was a bad idea to do everything with a GOTO 60 years ago shouldn't mean don't do some things with goto today.

Re: Goto (2007)

#100
post #4

Coming from assembly language, I always found the anti-goto sentiment rather cute. A beautiful restriction, but ultimately arbitrary. Like writing poetry. Or those novels that do not ever use the letter "e". Why would an otherwise sane person write code with "rep" and without ever using "jmp"?

Goto aversion, like single-entry/single-exit and everything anyone has ever said about 3rd-to-5th-generation programming languages, addresses a concern that hasn't been relevant in decades and that most modern programmers have no context for whatsoever.

The words have straightforward meanings, unfortunately, so they've since been recontextualized into settings where their prescriptions can still be followed, but the rationale doesn't hold up at all.

Post reply on HN