I wonder if Pink Floyd's Summer68 maybe refers to this. Other than that i am addicted and could not live without it. The other (terrible) song is from 1984 (east southern US). --steffen | |Der Kragenbaer, The moon bear, |der holt sich munter he cheerfully and one by one |einen nach dem anderen runter wa.ks himself off |(By Robert Gernhardt)
GOTO is one of those paradoxical things where I would only trust the most sophisticated engineer to know when it's acceptable to use a GOTO but on the flip side would be suspicious of anyone claiming to be an engineer that uses any amount of GOTOs...
Were any of the various GOTOs in languages ever meant to be any more than providing the same level of control that branch statements in assembly do? Was there ever some vision anyone's aware of concerning a sophisticated, dependable use of GOTOs? Since my first days poking around learning C GOTO has been mentally filed away as an assembly vestige for folks in transition, not a dependable construct in its own right. Any alternative camps out there?
- Matt G.
------- Original Message -------
On Thursday, March 9th, 2023 at 3:01 PM, Steffen Nurpmeso <steffen@sdaoden.eu> wrote:
> I wonder if Pink Floyd's Summer68 maybe refers to this.
> Other than that i am addicted and could not live without it.
> The other (terrible) song is from 1984 (east southern US).
>
> --steffen
> |
> |Der Kragenbaer, The moon bear,
> |der holt sich munter he cheerfully and one by one
> |einen nach dem anderen runter wa.ks himself off
> |(By Robert Gernhardt)
[-- Attachment #1: Type: text/plain, Size: 1450 bytes --] On Thu, Mar 9, 2023, 4:18 PM segaloco via TUHS <tuhs@tuhs.org> wrote: > GOTO is one of those paradoxical things where I would only trust the most > sophisticated engineer to know when it's acceptable to use a GOTO but on > the flip side would be suspicious of anyone claiming to be an engineer that > uses any amount of GOTOs... > > Were any of the various GOTOs in languages ever meant to be any more than > providing the same level of control that branch statements in assembly do? > Was there ever some vision anyone's aware of concerning a sophisticated, > dependable use of GOTOs? Since my first days poking around learning C GOTO > has been mentally filed away as an assembly vestige for folks in > transition, not a dependable construct in its own right. Any alternative > camps out there? > In C I use it all the time to do goto err for common error recovery because C doesn't have anything better. Warner > - Matt G. > > ------- Original Message ------- > On Thursday, March 9th, 2023 at 3:01 PM, Steffen Nurpmeso < > steffen@sdaoden.eu> wrote: > > > > I wonder if Pink Floyd's Summer68 maybe refers to this. > > Other than that i am addicted and could not live without it. > > The other (terrible) song is from 1984 (east southern US). > > > > --steffen > > | > > |Der Kragenbaer, The moon bear, > > |der holt sich munter he cheerfully and one by one > > |einen nach dem anderen runter wa.ks himself off > > |(By Robert Gernhardt) > [-- Attachment #2: Type: text/html, Size: 2174 bytes --]
[-- Attachment #1: Type: text/plain, Size: 2009 bytes --] I agree, unless I use setjmp/longjmp for that. Besides error recovery, there are occasionally other times when we want to locally "return" to a common state and start "from the top" again. I find such uses very clear in their intent, and if commented well, not hard to follow at all - as long as there is not more than one "top" :) On 03/09/2023 04:21 PM, Warner Losh wrote: > > > On Thu, Mar 9, 2023, 4:18 PM segaloco via TUHS <tuhs@tuhs.org > <mailto:tuhs@tuhs.org>> wrote: > > GOTO is one of those paradoxical things where I would only trust > the most sophisticated engineer to know when it's acceptable to > use a GOTO but on the flip side would be suspicious of anyone > claiming to be an engineer that uses any amount of GOTOs... > > Were any of the various GOTOs in languages ever meant to be any > more than providing the same level of control that branch > statements in assembly do? Was there ever some vision anyone's > aware of concerning a sophisticated, dependable use of GOTOs? > Since my first days poking around learning C GOTO has been > mentally filed away as an assembly vestige for folks in > transition, not a dependable construct in its own right. Any > alternative camps out there? > > > > In C I use it all the time to do goto err for common error recovery > because C doesn't have anything better. > > Warner > > - Matt G. > > ------- Original Message ------- > On Thursday, March 9th, 2023 at 3:01 PM, Steffen Nurpmeso > <steffen@sdaoden.eu <mailto:steffen@sdaoden.eu>> wrote: > > > > I wonder if Pink Floyd's Summer68 maybe refers to this. > > Other than that i am addicted and could not live without it. > > The other (terrible) song is from 1984 (east southern US). > > > > --steffen > > | > > |Der Kragenbaer, The moon bear, > > |der holt sich munter he cheerfully and one by one > > |einen nach dem anderen runter wa.ks himself off > > |(By Robert Gernhardt) > [-- Attachment #2: Type: text/html, Size: 3893 bytes --]
[-- Attachment #1: Type: text/plain, Size: 755 bytes --] This blog post compares the clarity of a number of programs written with goto vs. with other control flow methods: https://blog.joren.ga/gotophobia-harmful Knuth’s “Structured Programming with go to Statements” argues that we eventually missed the main point of structured programming by focusing too much on goto. https://pic.plover.com/knuth-GOTO.pdf Error handling (especially in loops or when releasing resources in non-RAII languages) and implementing state machines are commonly brought up as cases where goto is more fitting than common “structured” control flow statements. I think some newer languages like Zig extend the “break” mechanism to let you break to a label, so that sort of covers the first case. Josh [-- Attachment #2: Type: text/html, Size: 922 bytes --]
[-- Attachment #1: Type: text/plain, Size: 2083 bytes --] Oh also sometimes for breaking out of multiple levels of while/for loops. The alternatives are often worse. Warner On Thu, Mar 9, 2023, 4:31 PM Luther Johnson <luther@makerlisp.com> wrote: > I agree, unless I use setjmp/longjmp for that. Besides error recovery, > there are occasionally other times when we want to locally "return" to a > common state and start "from the top" again. I find such uses very clear in > their intent, and if commented well, not hard to follow at all - as long as > there is not more than one "top" :) > On 03/09/2023 04:21 PM, Warner Losh wrote: > > > > On Thu, Mar 9, 2023, 4:18 PM segaloco via TUHS <tuhs@tuhs.org> wrote: > >> GOTO is one of those paradoxical things where I would only trust the most >> sophisticated engineer to know when it's acceptable to use a GOTO but on >> the flip side would be suspicious of anyone claiming to be an engineer that >> uses any amount of GOTOs... >> >> Were any of the various GOTOs in languages ever meant to be any more than >> providing the same level of control that branch statements in assembly do? >> Was there ever some vision anyone's aware of concerning a sophisticated, >> dependable use of GOTOs? Since my first days poking around learning C GOTO >> has been mentally filed away as an assembly vestige for folks in >> transition, not a dependable construct in its own right. Any alternative >> camps out there? >> > > > In C I use it all the time to do goto err for common error recovery > because C doesn't have anything better. > > Warner > >> - Matt G. >> >> ------- Original Message ------- >> On Thursday, March 9th, 2023 at 3:01 PM, Steffen Nurpmeso < >> steffen@sdaoden.eu> wrote: >> >> >> > I wonder if Pink Floyd's Summer68 maybe refers to this. >> > Other than that i am addicted and could not live without it. >> > The other (terrible) song is from 1984 (east southern US). >> > >> > --steffen >> > | >> > |Der Kragenbaer, The moon bear, >> > |der holt sich munter he cheerfully and one by one >> > |einen nach dem anderen runter wa.ks himself off >> > |(By Robert Gernhardt) >> > > [-- Attachment #2: Type: text/html, Size: 4151 bytes --]
[-- Attachment #1: Type: text/plain, Size: 2774 bytes --] I guess I hadn't considered deeply nested loops. I contort myself into a mental pretzel figuring out how to avoid GOTOs sometimes, maybe I could stand to embrace one every once in a while myself... Now doing some research, more languages support GOTO than I thought, including C#, PHP, even Rust for all its safety orientation appears to at least muster a GOTO-ish construct. If people keep doing it, it must still be wanted, needed, and useful. I stand corrected on my never-GOTO attitude. Now to slip a GOTO into a work project and see how long it takes to get chastised :) - Matt G. ------- Original Message ------- On Thursday, March 9th, 2023 at 3:54 PM, Warner Losh <imp@bsdimp.com> wrote: > Oh also sometimes for breaking out of multiple levels of while/for loops. The alternatives are often worse. > > Warner > > On Thu, Mar 9, 2023, 4:31 PM Luther Johnson <luther@makerlisp.com> wrote: > >> I agree, unless I use setjmp/longjmp for that. Besides error recovery, there are occasionally other times when we want to locally "return" to a common state and start "from the top" again. I find such uses very clear in their intent, and if commented well, not hard to follow at all - as long as there is not more than one "top" :) >> >> On 03/09/2023 04:21 PM, Warner Losh wrote: >> >>> On Thu, Mar 9, 2023, 4:18 PM segaloco via TUHS <tuhs@tuhs.org> wrote: >>> >>>> GOTO is one of those paradoxical things where I would only trust the most sophisticated engineer to know when it's acceptable to use a GOTO but on the flip side would be suspicious of anyone claiming to be an engineer that uses any amount of GOTOs... >>>> >>>> Were any of the various GOTOs in languages ever meant to be any more than providing the same level of control that branch statements in assembly do? Was there ever some vision anyone's aware of concerning a sophisticated, dependable use of GOTOs? Since my first days poking around learning C GOTO has been mentally filed away as an assembly vestige for folks in transition, not a dependable construct in its own right. Any alternative camps out there? >>> >>> In C I use it all the time to do goto err for common error recovery because C doesn't have anything better. >>> >>> Warner >>> >>>> - Matt G. >>>> >>>> ------- Original Message ------- >>>> On Thursday, March 9th, 2023 at 3:01 PM, Steffen Nurpmeso <steffen@sdaoden.eu> wrote: >>>> >>>>> I wonder if Pink Floyd's Summer68 maybe refers to this. >>>>> Other than that i am addicted and could not live without it. >>>>> The other (terrible) song is from 1984 (east southern US). >>>>> >>>>> --steffen >>>>> | >>>>> |Der Kragenbaer, The moon bear, >>>>> |der holt sich munter he cheerfully and one by one >>>>> |einen nach dem anderen runter wa.ks himself off >>>>> |(By Robert Gernhardt) [-- Attachment #2: Type: text/html, Size: 5408 bytes --]
[-- Attachment #1: Type: text/plain, Size: 3201 bytes --] On Thu, Mar 9, 2023, 5:55 PM segaloco <segaloco@protonmail.com> wrote: > I guess I hadn't considered deeply nested loops. I contort myself into a > mental pretzel figuring out how to avoid GOTOs sometimes, maybe I could > stand to embrace one every once in a while myself... > Yea. I recall a proposal to add break label; and the label could only be at the end of a loop. The objection was why bloat the compiler with another goto... I developed my restricted lack of fear after a stint in Java with its multilevel break... Warner Now doing some research, more languages support GOTO than I thought, > including C#, PHP, even Rust for all its safety orientation appears to at > least muster a GOTO-ish construct. If people keep doing it, it must still > be wanted, needed, and useful. I stand corrected on my never-GOTO attitude. > Now to slip a GOTO into a work project and see how long it takes to get > chastised :) > > - Matt G. > ------- Original Message ------- > On Thursday, March 9th, 2023 at 3:54 PM, Warner Losh <imp@bsdimp.com> > wrote: > > Oh also sometimes for breaking out of multiple levels of while/for loops. > The alternatives are often worse. > > Warner > > On Thu, Mar 9, 2023, 4:31 PM Luther Johnson <luther@makerlisp.com> wrote: > >> I agree, unless I use setjmp/longjmp for that. Besides error recovery, >> there are occasionally other times when we want to locally "return" to a >> common state and start "from the top" again. I find such uses very clear in >> their intent, and if commented well, not hard to follow at all - as long as >> there is not more than one "top" :) >> On 03/09/2023 04:21 PM, Warner Losh wrote: >> >> >> >> On Thu, Mar 9, 2023, 4:18 PM segaloco via TUHS <tuhs@tuhs.org> wrote: >> >>> GOTO is one of those paradoxical things where I would only trust the >>> most sophisticated engineer to know when it's acceptable to use a GOTO but >>> on the flip side would be suspicious of anyone claiming to be an engineer >>> that uses any amount of GOTOs... >>> >>> Were any of the various GOTOs in languages ever meant to be any more >>> than providing the same level of control that branch statements in assembly >>> do? Was there ever some vision anyone's aware of concerning a >>> sophisticated, dependable use of GOTOs? Since my first days poking around >>> learning C GOTO has been mentally filed away as an assembly vestige for >>> folks in transition, not a dependable construct in its own right. Any >>> alternative camps out there? >>> >> >> >> In C I use it all the time to do goto err for common error recovery >> because C doesn't have anything better. >> >> Warner >> >>> - Matt G. >>> >>> ------- Original Message ------- >>> On Thursday, March 9th, 2023 at 3:01 PM, Steffen Nurpmeso < >>> steffen@sdaoden.eu> wrote: >>> >>> >>> > I wonder if Pink Floyd's Summer68 maybe refers to this. >>> > Other than that i am addicted and could not live without it. >>> > The other (terrible) song is from 1984 (east southern US). >>> > >>> > --steffen >>> > | >>> > |Der Kragenbaer, The moon bear, >>> > |der holt sich munter he cheerfully and one by one >>> > |einen nach dem anderen runter wa.ks himself off >>> > |(By Robert Gernhardt) >>> >> >> > [-- Attachment #2: Type: text/html, Size: 6312 bytes --]
> On Mar 9, 2023, at 15:18, segaloco via TUHS <tuhs@tuhs.org> wrote: > > GOTO is one of those paradoxical things where I would only trust the most sophisticated engineer to know when it's acceptable to use a GOTO but on the flip side would be suspicious of anyone claiming to be an engineer that uses any amount of GOTOs... > > Were any of the various GOTOs in languages ever meant to be any more than providing the same level of control that branch statements in assembly do? Was there ever some vision anyone's aware of concerning a sophisticated, dependable use of GOTOs? Since my first days poking around learning C GOTO has been mentally filed away as an assembly vestige for folks in transition, not a dependable construct in its own right. Any alternative camps out there? COBOL's ALTER statement is kind of analogous to a computed GOTO, but it adds a dangerous aspect of "action at a distance" (i.e., monkey-patching which invisibly modifies the control flow of the original code): "The ALTER statement changes the transfer point specified in a GO TO statement" https://www.mainframebug.com/tuts/COBOL/module7/Top18_COBOL_ALTER_statement.php "The ALTER Statement" https://www.microfocus.com/documentation/visual-cobol/vc60/DevHub/HRLHLHPDF803.html The problem, IMO, is that the compile-time program flow can be invisibly altered at run time, by code anywhere else in the program. So, there is no requirement that a given branch, GOTO, or noop statement will have its compile-time semantics. If used with restraint, this be used to optimize code paths, but it can easily be overused. Just as a GOTO is a surfacing of the assembler branch instruction(s), the ALTER is analogous to an old assembly-language trick (aka hack): dynamically modifying "br*/noop foo" commands. FWIW, I didn't use either the ALTER or the trick in my own code, but I did keep them in reserve (:-). In one of my earliest COBOL projects, the code came to me with an infestation of ALTER statements: specifically, a hierarchy of IF statements with ALTER statements at various levels. This was used at startup time, to configure the remainder of the program. All very elegant, but really overkill for the task at hand. As I explained to my boss, the ALTER statements made the code really difficult to understand. With his permission, I removed the nest of ALTERs and reworked the remaining control flow as needed. I was greatly assisted in this by the fact that I could retain the DATA DIVISION as-is, and merely implement the (rather prosaic) control flow that we actually used. And no, I don't want to return to either assembler or COBOL (:-). -r
On Thu, 9 Mar 2023, Warner Losh wrote:
> In C I use it all the time to do goto err for common error recovery
> because C doesn't have anything better.
<AOL>
Me too :-)
</AOL>
Seriously, I also use setjmp()/longjmp() for a more elegant exit from a
deeply-nested loop; "break N" to break out of "N" loops, anyone? I
haven't found that yet...
Of course, in those days it was setexit() etc :-)
-- Dave
Hi Werner,
> after a stint in Java with its multilevel break...
Given sh(1)'s break takes an optional number of loops to break out of,
I'm surprised C stuck with just the single-level break.
--
Cheers, Ralph.
> From: Warner Losh > In C I use it all the time to do goto err for common error recovery > because C doesn't have anything better. That's because C doesn't have 'conditions'. (Apparently, from the following posts, most people here are unfamiliar with them. Too bad, they are a great idea. OK summary here: http://gunkies.org/wiki/Condition_handler for those who are unfamiliar with the idea.) I was at one point writing a compiler using a recursive descent parser, and decided the code would be a lot simpler/cleaner if I had them. (If, for example, one discovers discovers an un-expected 'end of file', there can be an extremely large number of procedure invocations in between where that is discovered, and where it is desirable to handle it. So every possible intervening procedure would have to have an 'unexpected EOF' return value, one would have to write code in every possible intervening procedure to _handle_ an 'unexpected EOF' return value, etc.)' (Yes, I could have used setjmp/longjmp; those are effectively a limited version of condition handlers.) Since C has a stack, it was relatively easy to implement, without any compiler support: on() became a macro for 'if _on("condition_name")'; _on() was a partially-assembler procedure which i) stacked the handler (I forget where I put it; I may have created a special 'condition stack', to avoid too many changes to the main C stack), and ii) patched the calling procedure's return point to jump to some code that unstacked the handler, and iii) returned 'false'. If the condition occurred, a return from _on() was simulated, returning 'true', etc. So the code had things like: on ("unexpected EOF") { code to deal with it } With no compiler support, it added a tiny bit of overhead (stacking/unstacking conditions), but not too bad. John Wroclawski and someone implemented a very similar thing entirely in C; IIRC it was built on top of setjmp/longjmp. I don't recall how it dealt with un-stacking handlers on exit (which mine did silently). Noel
Ralph Corderoy <ralph@inputplus.co.uk> wrote:
> Hi Werner,
>
> > after a stint in Java with its multilevel break...
>
> Given sh(1)'s break takes an optional number of loops to break out of,
> I'm surprised C stuck with just the single-level break.
C predates the Bourne shell by several years. Remember too that the
C compiler had to fit in a small space; having multilevel or labelled
breaks requires more bookkeeping.
The idea of labelled loops is not at all new, Ada had them in the 80s
and it wasn't new then. IIRC Go also provides them.
Arnold
> From: Warner Losh > for breaking out of multiple levels of while/for loops. Yeah, multi-level 'breaks' were one of the things I really missed in C. The other was BCPL's 'VALOF/RESULTIS'. Back before C compilers got good enough to do inline substitutions of small procedures (making macros with arguments less useful), it would have been nice to have, for macros that wanted to return something. Instead, one had to stand on one's head and use a '(cond ? ret1 : ret2 )' of some form. Noel
Hi Arnold, > > > after a stint in Java with its multilevel break... > > > > Given sh(1)'s break takes an optional number of loops to break out of, > > I'm surprised C stuck with just the single-level break. > > C predates the Bourne shell by several years. Yes, but C was evolving. As it aged and spread in use, I agree it could change less easily. > Remember too that the C compiler had to fit in a small space; having > multilevel or labelled breaks requires more bookkeeping. Is it more bookkeeping than is already needed to handle the ends of the nested for-loops, say? -- Cheers, Ralph.
Ralph Corderoy <ralph@inputplus.co.uk> wrote:
> > Remember too that the C compiler had to fit in a small space; having
> > multilevel or labelled breaks requires more bookkeeping.
>
> Is it more bookkeeping than is already needed to handle the ends of the
> nested for-loops, say?
Yes, since you have to keep track of a label in a table somewhere
that you can look up. Is it *that* much more that the PDP-11 C compiler
could not have handled it? I don't know.
Arnold
Hi Arnold, > > > Remember too that the C compiler had to fit in a small space; > > > having multilevel or labelled breaks requires more bookkeeping. > > > > Is it more bookkeeping than is already needed to handle the ends of > > the nested for-loops, say? > > Yes, since you have to keep track of a label in a table somewhere that > you can look up. Oh, I think our wires are crossed. I wrote: > Given sh(1)'s break takes an optional number of loops to break out of, > I'm surprised C stuck with just the single-level break. In other words, ‘break 2’ works in sh but not in C. You added labelled breaks; I wasn't asking if they upped the housekeeping, just ‘break 2’. -- Cheers, Ralph.
Multilevel breaks are as bad as goto with regard to structure violation.
------ Original Message ------
From "Noel Chiappa" <jnc@mercury.lcs.mit.edu>
To tuhs@tuhs.org
Date 3/10/2023 6:51:45 AM
Subject [TUHS] Re: I can't drive 55: "GOTO considered harmful" 55th
anniversary
> > From: Warner Losh
>
> > for breaking out of multiple levels of while/for loops.
>
>Yeah, multi-level 'breaks' were one of the things I really missed in C.
>
>
[-- Attachment #1: Type: text/plain, Size: 255 bytes --] On Fri, Mar 10, 2023 at 9:16 AM Ronald Natalie <ron@ronnatalie.com> wrote: Multilevel breaks are as bad as goto with regard to structure violation. > No more so than `return` statements in arbitrary places, which nobody worries about any more. [-- Attachment #2: Type: text/html, Size: 920 bytes --]
> From: "Ronald Natalie" > Multilevel breaks are as bad as goto with regard to structure violation. In a way, you are right. There isn't really much difference between: for (mumble) { for (foobar) { do some stuff break-2; } } and: for (mumble) { for (foobar) { do some stuff goto all_loops_done; } } all_loops_done: The former is basically just 'syntactic sugar' for the latter. I think the point is that goto's aren't necessarily _always_ bad, in and of themselves; it's _how_, _where_ and _why_ one uses them. If one uses goto's in a _structured_ way (oxymoronic as that sounds), to get around things that are lacking in the language's flow-control, they're probably fine. Then, of course, one gets into the usual shrubbery of 'but suppose someone uses them in a way that's _not_ structured?' There's no fixing stupid, is my response. Nested 'if/then/else' can be used to write comletely incomprehensible code (I have an amusing story about that) - but that's not an argument against nested 'if/then/else'. As I've said before, the best sculpting tools in the world won't make a great sculptor out of a ham-handed bozo. Noel
I've used gotos for decades but in a "structured" way. My functions have a pattern: <allocation section> <work section> <deallocation section> and there are a series of labels in the deallocation section. Then while you are wandering through the allocation section, you can jump to the right spot in the deallocation section. And yes, this is a simplification because I initialize all my pointers to NULL so the deallocation is all if (p) free(p); but the idea is the same. You wind up some state and wind down some state and the gotos are used to jump to the right place to unwind. On Fri, Mar 10, 2023 at 10:37:02AM -0500, Noel Chiappa wrote: > > From: "Ronald Natalie" > > > Multilevel breaks are as bad as goto with regard to structure violation. > > In a way, you are right. There isn't really much difference between: > > for (mumble) { > for (foobar) { > do some stuff > break-2; > } > } > > and: > > for (mumble) { > for (foobar) { > do some stuff > goto all_loops_done; > } > } > all_loops_done: > > > The former is basically just 'syntactic sugar' for the latter. > > I think the point is that goto's aren't necessarily _always_ bad, in and of > themselves; it's _how_, _where_ and _why_ one uses them. If one uses goto's > in a _structured_ way (oxymoronic as that sounds), to get around things that > are lacking in the language's flow-control, they're probably fine. > > Then, of course, one gets into the usual shrubbery of 'but suppose someone > uses them in a way that's _not_ structured?' There's no fixing stupid, is my > response. Nested 'if/then/else' can be used to write comletely > incomprehensible code (I have an amusing story about that) - but that's not > an argument against nested 'if/then/else'. > > As I've said before, the best sculpting tools in the world won't make a great > sculptor out of a ham-handed bozo. > > Noel -- --- Larry McVoy Retired to fishing http://www.mcvoy.com/lm/boat
On Fri, Mar 10, 2023 at 6:37 AM Noel Chiappa <jnc@mercury.lcs.mit.edu> wrote: > > > From: Warner Losh > > > In C I use it all the time to do goto err for common error recovery > > because C doesn't have anything better. > > That's because C doesn't have 'conditions'. (Apparently, from the following > posts, most people here are unfamiliar with them. Too bad, they are a great > idea. OK summary here: > > http://gunkies.org/wiki/Condition_handler > > for those who are unfamiliar with the idea.) I don't know if I'd say they're a great idea. The problem with exceptions (nee conditions, though I most often associate the term "condition" with Lisp, and in particular Common Lisp's implementation has a rather different flavor in the ability to restart execution _at the point where the condition was raised_, even if the handler is conceptually much higher up in the call stack) is that they introduce non-linear control flow, which can be very difficult to reason about. This is especially challenging in code that may allocate resources and must manually deallocate them (such as C); without some notion of RAII or finalizers for arbitrary objects. It's really easy to introduce leaks in code with exceptions, and while often this is for memory, where you're ok if you're in a garbage collected language, you're gonna have a bad day when it's for something like file descriptors (which are much scarcer than memory). Unless pretty much everything is behind a stack guard, or whatever the moral equivalent in your language is, you're constrained to handling the errors at many places in the call stack, in which case, why bother? But the point about error handling and the use of `goto` in C in lieu of something better is well taken, and conditions are _a_ reasonable mechanism for dealing with the issue. I'd argue that a `Result` monad and some short-circuiting sugar used in conjunction with RAII is another that is better. For example in Rust, the result type interacts with the `?` operator so that, if a call returns a `Result<T, E>`, the T will be unwrapped if the result is Ok(T), otherwise, the code will return `Err(E)`. So one can write code that has the brevity of exceptions without introducing the control-flow weirdness: fn make_request(host: &str) -> std::io::Result<()> { let req = "hi\r\n".as_bytes(); std::net::TcpStream::connect(host)?.write(req)?; Ok(()) } (Note that the TCP stream will be "dropped" after the call to `write`, and the drop impl on the TcpStream type will close the socket.) Combined with pattern matching on the error type, this is quite expressive. > I was at one point writing a compiler using a recursive descent parser, and > decided the code would be a lot simpler/cleaner if I had them. (If, for > example, one discovers discovers an un-expected 'end of file', there can be > an extremely large number of procedure invocations in between where that is > discovered, and where it is desirable to handle it. So every possible > intervening procedure would have to have an 'unexpected EOF' return value, > one would have to write code in every possible intervening procedure to > _handle_ an 'unexpected EOF' return value, etc.)' > > (Yes, I could have used setjmp/longjmp; those are effectively a limited > version of condition handlers.) > > Since C has a stack, it was relatively easy to implement, without any compiler > support: on() became a macro for 'if _on("condition_name")'; _on() was a > partially-assembler procedure which i) stacked the handler (I forget where I > put it; I may have created a special 'condition stack', to avoid too many > changes to the main C stack), and ii) patched the calling procedure's return > point to jump to some code that unstacked the handler, and iii) returned > 'false'. If the condition occurred, a return from _on() was simulated, > returning 'true', etc. > > So the code had things like: > > on ("unexpected EOF") { > code to deal with it > } > > With no compiler support, it added a tiny bit of overhead > (stacking/unstacking conditions), but not too bad. > > John Wroclawski and someone implemented a very similar thing > entirely in C; IIRC it was built on top of setjmp/longjmp. I don't > recall how it dealt with un-stacking handlers on exit (which mine > did silently). The plan9 kernel has something remarkably similar; there is a pre-process error stack containing the local equivalent of a bunch of `jmp_buf`'s. One could write, `if (waserror()) { /* handle cleanup */ }` where, `waserror` would push a jmp_buf onto the stack a la the `setjmp` equivalent. Code later on could call `error(Ewhatever)` and that would cache the error somewhere in the proc struct and invoke the `longjmp` equivalent to jump back to the label at the top of the stack, where `waserror()` would now return 1. Things would have to manually `poperror()`, to pop the stack. I'm told that the plan9 C compilers were callee-save in part to keep these state labels svelte. This got pulled into the Akaros kernel at one point, and for a while, we had someone working with us who was pretty prominent in the Linux community. What was interesting was that he was so used to the `goto err;` convention from that world that he just could not wrap his head around how the `waserror()` stuff worked; at one point there was a sequence like, char *foo; if (waserror()) { free(foo); return -1; } foo = malloc(len); something(); free(foo); return 0; ...and the guy just couldn't get how the code inside of the `waserror()` wasn't trashing the system, since obviously the malloc was done after `waserror()`, and so the pointer was meaningless at that point. It took quite a while to explain what was going on. Btw: I was once told by a reliable authority that the Go developers considered implementing exceptions, but decided against it because of the cognitive load it imposes. - Dan C.
On Fri, Mar 10, 2023 at 10:37 AM Noel Chiappa <jnc@mercury.lcs.mit.edu> wrote:
>[snip]
> I think the point is that goto's aren't necessarily _always_ bad, in and of
> themselves; it's _how_, _where_ and _why_ one uses them. If one uses goto's
> in a _structured_ way (oxymoronic as that sounds), to get around things that
> are lacking in the language's flow-control, they're probably fine.
Something that I think was likely a useful outcome of Djikstra's
polemic is that people began looking at what they were using goto for
and the things that were useful were extracted and codified as
first-class mechanisms in lots of languages (e.g., `break` and
`continue` for loops; exceptions; early function returns;
multilevel-break where that's a thing in a particular language, etc).
Goto is sort of like a hammer stone, it's useful for all kinds of
things, but it's difficult to control without practice and patience.
You can probably cut a diamond with one, but why endure the difficulty
and take the risk if you have access to a jeweler's hammer?
- Dan C.
ron@ronnatalie.com wrote: > Multilevel breaks are as bad as goto with regard to structure violation. Back when I was in compilers (so long ago, that it was the DEC PDP-10 FORTRAN compiler(*)) my recall is that break/continue never generated irreducible flow graphs, as goto can: https://en.wikipedia.org/wiki/Control-flow_graph#Reducibility I still remember the days when you could find C code written by PASCAL programmers, littered with condition variables on loops, and if statements to not execute the tail of the loop body if the loop condition was false. (*) The FORTRAN compiler was written in BLISS-10, which had labeled statements, and a "leave <label>" construct which was only legal inside the labeled statement: http://www.bitsavers.org/pdf/dec/pdp10/TOPS10/DEC-10-LBRMA-A-D_BLISS-10_Programmers_Manual_Ver_4_Feb74.pdf#page=42
Dave Horsfall wrote in <alpine.BSF.2.21.9999.2303101657460.4881@aneurin.horsfall.org>: |On Thu, 9 Mar 2023, Warner Losh wrote: |> In C I use it all the time to do goto err for common error recovery |> because C doesn't have anything better. | |<AOL> |Me too :-) |</AOL> | |Seriously, I also use setjmp()/longjmp() for a more elegant exit from a That is sheer unbelievable, really? _So_ expensive! |deeply-nested loop; "break N" to break out of "N" loops, anyone? I |haven't found that yet... Very often i find myself needing a restart necessity, so "continue N" would that be. Then again when "N" is a number instead of a label this is a (let alone maintainance) mess but for shortest code paths. All the "replacements", like closures, plain inner functions, even more contorted conditionals (i think in the last seven days i saw at least three fixes fly by due to logic errors in contorted conditionals, tiny C compiler, OpenBSD i think bpf/bgpd?, and some FreeBSD commit, which sums up as "Pascal: no"), and "state machine indicating variables" are not as elegant and cheap, and do not allow an as human-receivable control flow (imho), as a simple jump can be. Like my always quoted exampe that adds unnecessary conditionals which evaluate over and over again for nothing if(defined($nl = $self->begin_line)){ $self->begin_line(undef); $self->seen_endl(1); $ogoditisanewperl = 1 #goto jumpin; } while($ogoditisanewperl || ($nl = readline $self->infh)){ if(!$ogoditisanewperl){ ++${$self->__lineno}; $self->seen_endl($nl =~ s/(.*?)\s+$/$1/) } $ogoditisanewperl = 0; #jumpin: |Of course, in those days it was setexit() etc :-) ENTRY(setexit, 0) movab setsav,r0 movq r6,(r0)+ movq r8,(r0)+ movq r10,(r0)+ movq 8(fp),(r0)+ # ap, fp movab 4(ap),(r0)+ # sp movl 16(fp),(r0) # pc clrl r0 ret ENTRY(reset, 0) movl 4(ap),r0 # returned value movab setsav,r1 movq (r1)+,r6 movq (r1)+,r8 movq (r1)+,r10 movq (r1)+,r12 movl (r1)+,sp jmp *(r1) setsav: .space 10*4 .text Cheap it is not. But maybe cheaper than calling a closure or inner function with all the (repeated) stack setup and unwinding. |-- Dave --End of <alpine.BSF.2.21.9999.2303101657460.4881@aneurin.horsfall.org> --steffen | |Der Kragenbaer, The moon bear, |der holt sich munter he cheerfully and one by one |einen nach dem anderen runter wa.ks himself off |(By Robert Gernhardt)
> On Mar 10, 2023, at 8:56 AM, Steffen Nurpmeso <steffen@sdaoden.eu> wrote:
>
> |Seriously, I also use setjmp()/longjmp() for a more elegant exit from a
>
> That is sheer unbelievable, really? _So_ expensive!
>
> |deeply-nested loop; "break N" to break out of "N" loops, anyone? I
> |haven't found that yet...
I suspect Dave means deeply nested function calls.
[-- Attachment #1: Type: text/plain, Size: 1205 bytes --] On Fri, Mar 10, 2023 at 9:16 AM Ronald Natalie <ron@ronnatalie.com> wrote: > Multilevel breaks are as bad as goto with regard to structure violation. > Amen. My memory of the argument at the time was one of pick your poison. Each language has trade-offs and it depends on what you value. C was considered "dirty" by many CS types in the day compared to languages like Pascal, Simula67, Algol-X. I've always said the key was what was left out of the language, not what was put in. Dennis offers a few important pieces of wisdom here: - "When I read commentary about suggestions for where C should go, I often think back and give thanks that it wasn't developed under the advice of a worldwide crowd." - "A language that doesn't have everything is actually easier to program in than some that do." - "C is quirky, flawed, and an enormous success." Arnold's observation about trying to be small is reasonable, although contemporaries like BLISS did have support. So the comparison should really be to BCPL, PL/360, BLISS, *et al*. for features/size [although Wulf cheated, the BLISS-11 compiler was not self-hosting and needed a PDP-10 to run it]. ᐧ [-- Attachment #2: Type: text/html, Size: 2850 bytes --]
Phil Budne wrote in <202303101630.32AGU2OD008070@ultimate.com>: |ron@ronnatalie.com wrote: |> Multilevel breaks are as bad as goto with regard to structure violation. | |Back when I was in compilers (so long ago, that it was the DEC PDP-10 |FORTRAN compiler(*)) my recall is that break/continue never generated |irreducible flow graphs, as goto can: | |https://en.wikipedia.org/wiki/Control-flow_graph#Reducibility | |I still remember the days when you could find C code written by PASCAL |programmers,[.] |littered[.] I love this. |with condition variables on loops, and if |statements to not execute the tail of the loop body if the loop |condition was false. | |(*) The FORTRAN compiler was written in BLISS-10, which had labeled |statements, and a "leave <label>" construct which was only legal |inside the labeled statement: | |http://www.bitsavers.org/pdf/dec/pdp10/TOPS10/DEC-10-LBRMA-A-D_BLISS-10_\ |Programmers_Manual_Ver_4_Feb74.pdf#page=42 --End of <202303101630.32AGU2OD008070@ultimate.com> --steffen | |Der Kragenbaer, The moon bear, |der holt sich munter he cheerfully and one by one |einen nach dem anderen runter wa.ks himself off |(By Robert Gernhardt)
On 3/10/23, Clem Cole <clemc@ccc.com> wrote:
>
> Arnold's observation about trying to be small is reasonable,
> although contemporaries like BLISS did have support. So the comparison
> should really be to BCPL, PL/360, BLISS, *et al*. for features/size
> [although Wulf cheated, the BLISS-11 compiler was not self-hosting and
> needed a PDP-10 to run it].
For what it's worth, BLISS does not have a GOTO expression (BLISS
doesn't have statements per se--everything is an expression and can be
used as a value).
Wulf was studying code optimization. His BLISS-11 compiler, and its
successor at DEC, BLISS-16, implemented many advanced (for the day)
optimizations. In the programming environments at CMU and DEC it was
easier to suffer the mild inconvenience of cross-compilation than to
try to shoehorn the compiler into a 16-bit address space.
It certainly would be possible to implement a native BLISS compiler
for the PDP-11, but you'd have to sacrifice either some of the
optimizations or take a big hit in compilation speed.
-Paul W.
> Phil Budne wrote in
> <202303101630.32AGU2OD008070@ultimate.com>:
> |ron@ronnatalie.com wrote:
> |
> |I still remember the days when you could find C code written by PASCAL
> |programmers,[.]
Someone once observed that a skilled FORTRAN programmer could write
FORTRAN in any programming language.
-Paul W.
> On Mar 10, 2023, at 12:57 PM, Paul Winalski <paul.winalski@gmail.com> wrote:
>
>> Phil Budne wrote in
>> <202303101630.32AGU2OD008070@ultimate.com>:
>> |ron@ronnatalie.com wrote:
>> |
>> |I still remember the days when you could find C code written by PASCAL
>> |programmers,[.]
>
> Someone once observed that a skilled FORTRAN programmer could write
> FORTRAN in any programming language.
>
> -Paul W.
Once taught a programming languages class at Stanford, with assignments in Pascal, APL, LISP, and SNOBOL. The SNOBOL was to solve a crossword by pattern matching, given the grid and the solution words.
One kid had by far the fastest solution, in SNOBOL, but if you held up the listing at arm’s length you would swear it was FORTRAN.
I write my FORTRAN code in C these days.
-L
That’s my point. Both break structure.
Just hinding the break with some construct that isn’t “goto” doesn’t
make it acceptable.
------ Original Message ------
From "Noel Chiappa" <jnc@mercury.lcs.mit.edu>
To tuhs@tuhs.org
Date 3/10/2023 10:37:02 AM
Subject [TUHS] Re: I can't drive 55: "GOTO considered harmful" 55th
anniversary
> > From: "Ronald Natalie"
>
> > Multilevel breaks are as bad as goto with regard to structure violation.
>
>In a way, you are right. There isn't really much difference between:
>
>
On Fri, Mar 10, 2023 at 1:55 PM Ron Natalie <ron@ronnatalie.com> wrote:
> That’s my point. Both break structure.
>
> Just hinding the break with some construct that isn’t “goto” doesn’t
> make it acceptable.
The alternative is often worse, though. I'd take a well-aimed goto or
a nested break over a bunch of conditionals in the bodies of loops any
day, both in terms of readability and performance.
That said, I'm not a huge fan of the `goto fail;` pattern. Apple had a
pretty major bug with that, and I find that many, many times it can be
replaced with a restructuring of the code. For example, perhaps do
your allocation, call a function and capture the return value (passing
the allocated resources as arguments), and then de-allocate and return
the cached return value. Let the compiler optimize it.
As an experiment, I rewrote the Apple bug code (which was open source)
to do that and it was cleaner and simpler than the original. Someone I
showed it to said, "but what, are you going to do that for _every_
function that can fail?" Well no, but generally you don't have to; we
fixate too much on the general problem and ignore the specifics.
- Dan C.
That's a good point about the specifics, there's no one-size-fits-all error condition that describes every possible exceptional circumstance, so how could there be one singular best practice for handling the abstract concept of an "error".
Plus, given one person's error is another person's business logic sometimes...if we can't agree on what an error is, how can a computer be expected to :P
- Matt G.
------- Original Message -------
On Friday, March 10th, 2023 at 11:04 AM, Dan Cross <crossd@gmail.com> wrote:
> On Fri, Mar 10, 2023 at 1:55 PM Ron Natalie ron@ronnatalie.com wrote:
>
> > That’s my point. Both break structure.
> >
> > Just hinding the break with some construct that isn’t “goto” doesn’t
> > make it acceptable.
>
>
> The alternative is often worse, though. I'd take a well-aimed goto or
> a nested break over a bunch of conditionals in the bodies of loops any
> day, both in terms of readability and performance.
>
> That said, I'm not a huge fan of the `goto fail;` pattern. Apple had a
> pretty major bug with that, and I find that many, many times it can be
> replaced with a restructuring of the code. For example, perhaps do
> your allocation, call a function and capture the return value (passing
> the allocated resources as arguments), and then de-allocate and return
> the cached return value. Let the compiler optimize it.
>
> As an experiment, I rewrote the Apple bug code (which was open source)
> to do that and it was cleaner and simpler than the original. Someone I
> showed it to said, "but what, are you going to do that for every
> function that can fail?" Well no, but generally you don't have to; we
> fixate too much on the general problem and ignore the specifics.
>
> - Dan C.
Dan Cross <crossd@gmail.com> once said:
> I'm told that the plan9 C compilers were callee-save in part to keep
> these state labels svelte.
The Plan 9 compilers are caller-save. That means the labels only have
to contain pc and sp. Waserror works well except for one small issue
involving whether or not the compiler decides to store a value to a
non-volatile, non-pointer variable when the value would not be used
after a function call. As in:
int a;
a = 1;
if(waserror()){ /* ... */ }
a = 2;
a = foo(a);
The waserror branch may see a == 1 if foo errors.
Ken's compilers are great, though. They don't engage in antisocial
optimizations based on dubious notions of undefined behavior. I'd
prefer my compiler to not elide explicit null checks or loads and
stores from a pointer.
Cheers,
Anthony
[-- Attachment #1: Type: text/plain, Size: 1443 bytes --] On Sun, Mar 12, 2023, 3:39 AM Anthony Martin <ality@pbrane.org> wrote: > Dan Cross <crossd@gmail.com> once said: > > I'm told that the plan9 C compilers were callee-save in part to keep > > these state labels svelte. > > The Plan 9 compilers are caller-save. That means the labels only have > to contain pc and sp. Indeed. I typo-ed but meant caller-save; it wouldn't be very svelte if it were the other way around. ;-) Waserror works well except for one small issue > involving whether or not the compiler decides to store a value to a > non-volatile, non-pointer variable when the value would not be used > after a function call. As in: > > int a; > a = 1; > if(waserror()){ /* ... */ } > a = 2; > a = foo(a); > > The waserror branch may see a == 1 if foo errors. > > Ken's compilers are great, though. They don't engage in antisocial > optimizations based on dubious notions of undefined behavior. I'd > prefer my compiler to not elide explicit null checks or loads and > stores from a pointer. It is certainly a shame that modern compiler writers have become essentially hostile to programmers in their pursuit of ever more aggressive optimizations based on rigid readings of the standard, common sense be damned. As for the plan9 C _language_, in the late 80s, it was arguably an improvement over what ANSI put out. Nowadays, however, I think the inverse is true. *Shrug* - Dan C. [-- Attachment #2: Type: text/html, Size: 2327 bytes --]
On 3/12/23, Dan Cross <crossd@gmail.com> wrote:
>
> It is certainly a shame that modern compiler writers have become
> essentially hostile to programmers in their pursuit of ever more aggressive
> optimizations based on rigid readings of the standard, common sense be
> damned.
As a compiler developer for many years, IMO the best compilers accept
a wide variety of variations and extensions to the language standard,
but have a strict-standard mode for those who want it.
Dave Cutler's DECwest organization developed and released s C89
compiler for Ultrix that accepted only strict, standard-conforming
syntax and semantics. No K&R mode, nothing but pure C89. One
customer called it the Rush Limbaugh of C compilers--extremely
conservative, and you can't reason with it.
-Paul W.
On Fri, 10 Mar 2023, Steffen Nurpmeso wrote:
> |Seriously, I also use setjmp()/longjmp() for a more elegant exit from a
>
> That is sheer unbelievable, really? _So_ expensive!
How often would you call setjmp()/longjmp()?
-- Dave
[-- Attachment #1: Type: text/plain, Size: 486 bytes --] On Sun, Mar 12, 2023, 2:47 PM Dave Horsfall <dave@horsfall.org> wrote: > On Fri, 10 Mar 2023, Steffen Nurpmeso wrote: > > > |Seriously, I also use setjmp()/longjmp() for a more elegant exit from a > > > > That is sheer unbelievable, really? _So_ expensive! > > How often would you call setjmp()/longjmp() > Cheap enough for occasional error handling, way too expensive for a generic exception handling system... processors with lots of registers were more of a problem... Warner > [-- Attachment #2: Type: text/html, Size: 1221 bytes --]
Warner Losh wrote in <CANCZdfqOZ3wrHktZGk3BrHV5ZdbkDyRPGxH61Mq87TVDQRQh7A@mail.gmail.com>: |On Sun, Mar 12, 2023, 2:47 PM Dave Horsfall <dave@horsfall.org> wrote: |> On Fri, 10 Mar 2023, Steffen Nurpmeso wrote: |> |>>|Seriously, I also use setjmp()/longjmp() for a more elegant exit from a |>> |>> That is sheer unbelievable, really? _So_ expensive! |> |> How often would you call setjmp()/longjmp() Only on a Sunday! I never used these myself of free will. (And never regulary at all until i took maintainership of a BSD Mail clone, which is the examplary piece of software to show that BSD signal handling and SA_RESTART are a terrible misconception, especially as soon as the software gets larger. .. In my opinion. Once it was able to run "24/6" i counted the number of system calls necessary for signal block / release and installation / removal over a week, and i think the number was way in the six digits. System calls them all! I should have taken the OpenBSD variant instead, and simply take over what "was good", and it would be much, much better by now. They did the work and reduced the very messy part to two exactly locatable system call points of interest. (I looked i guess 2014-<2017.) A very bad decision. But if i live long enough i will make it, and another one i would really long for.) |Cheap enough for occasional error handling, way too expensive for a generic |exception handling system... processors with lots of registers were more of |a problem... Even on a x86(-32) i have gnashed with my teeth. And that with a Cyrix from 1996 .. and not to think about i386 or even earlier processors with so few memory and speed. I remember _for sure_ looking at the jmpbuf structure by then, and the assembler files (sheer magic by then) and x86 instructions. "Some" jpeg library used jump buffers to signal errors. (I got rid of most sources for things that will never come true, but i do have libjpeg-turbo ball due to package dependencies, and they also use that internally, but looking at it it seems to be a different thing.) That is maybe ok since image processing is maybe expensive enough by itself to simply say they do not care about proper error paths along the way but take a "dead-end exit". (But it was i think not like that with the jpeg i have in mind.) --steffen | |Der Kragenbaer, The moon bear, |der holt sich munter he cheerfully and one by one |einen nach dem anderen runter wa.ks himself off |(By Robert Gernhardt)
[ Followups to COFF, as this is rapidly becoming a Unix tutorial ] On Sun, 12 Mar 2023, Warner Losh wrote: > > How often would you call setjmp()/longjmp()? > > Cheap enough for occasional error handling, way too expensive for a > generic exception handling system... processors with lots of registers > were more of a problem... I've only ever used it when knee-deep in procedure calls, and I needed to parachute back to the main loop when things went pear-shaped[*]; failure was not an option :-) On Sun, 12 Mar 2023, Steffen Nurpmeso wrote: > |> How often would you call setjmp()/longjmp() > > Only on a Sunday! Sometimes I did my best work outside of M-F 9-5 :-) > I never used these myself of free will. > > (And never regulary at all until i took maintainership of a BSD Mail > clone, which is the examplary piece of software to show that BSD signal > handling and SA_RESTART are a terrible misconception, especially as soon > as the software gets larger. .. In my opinion. Once it was able to run > "24/6" i counted the number of system calls necessary for signal block / > release and installation / removal over a week, and i think the number > was way in the six digits. System calls them all! I should have taken > the OpenBSD variant instead, and simply take over what "was good", and > it would be much, much better by now. They did the work and reduced the > very messy part to two exactly locatable system call points of interest. > (I looked i guess 2014-<2017.) A very bad decision. But if i live long > enough i will make it, and another one i would really long for.) I've never liked the concept of signals, especially for IPC; it's akin to being hit over the head with a lump of 4x2. Hardware interrupts were one thing, but it seemed to be a bit brutal in software. And no, I don't have an elegant solution short of message-passing. Heck, I still have nightmares about BSDi's "fdump" program using signals to coordinate its various children, and completely screwing up my backups as a result... > Even on a x86(-32) i have gnashed with my teeth. And that with > a Cyrix from 1996 .. and not to think about i386 or even earlier > processors with so few memory and speed. > I remember _for sure_ looking at the jmpbuf structure by then, and > the assembler files (sheer magic by then) and x86 instructions. You can read X86 assembler? I can only do that after a few stiff drinks... I did buy the book (in order to debug a floating bug defect in the optimiser -- hey, let's optimise this instruction right out! -- and I've never trusted optimisers since). [*] Cue the saying about it being impossible to design a foolproof system. -- Dave, the iconoclast
[-- Attachment #1: Type: text/plain, Size: 644 bytes --] On Sun, Mar 12, 2023 at 7:40 AM Dan Cross <crossd@gmail.com> wrote: > It is certainly a shame that modern compiler writers have become > essentially hostile to programmers in their pursuit of ever more aggressive > optimizations based on rigid readings of the standard, common sense be > damned. > Not at all. It is clear that mainstream C and C++ compilers optimize for the features most important to mainstream C and C++ programmers, which are: 1) Execution speed. 2) Execution speed. 3) I lied; there is no 3. If those are not your priorities, use a non-mainstream compiler or a different programming language. [-- Attachment #2: Type: text/html, Size: 2211 bytes --]
[-- Attachment #1: Type: text/plain, Size: 876 bytes --] On Mon, Mar 13, 2023, 04:26 John Cowan <cowan@ccil.org> wrote: > > > On Sun, Mar 12, 2023 at 7:40 AM Dan Cross <crossd@gmail.com> wrote: > > >> It is certainly a shame that modern compiler writers have become >> essentially hostile to programmers in their pursuit of ever more aggressive >> optimizations based on rigid readings of the standard, common sense be >> damned. >> > > Not at all. It is clear that mainstream C and C++ compilers optimize for > the features most important to mainstream C and C++ programmers, which are: > > 1) Execution speed. > > 2) Execution speed. > > 3) I lied; there is no 3. > > If those are not your priorities, use a non-mainstream compiler or a > different programming language. > Or you can ask GCC to respect your view of the language with things like -fno-strict-aliasing, -fwrapv, and -fno-trapv. > [-- Attachment #2: Type: text/html, Size: 2916 bytes --]
On Mon, Mar 13, 2023 at 6:41 AM Alejandro Colomar (man-pages)
<alx.manpages@gmail.com> wrote:
> Or you can ask GCC to respect your view of the language with things like -fno-strict-aliasing, -fwrapv, and -fno-trapv.
The problem that is that you are then no longer programming in "C",
but rather some dialect of "C" that happens to share the same syntax,
but with different semantics. That may be fine, or it may not, but it
can lead to all sorts of footgun traps if one is not careful.
- Dan C.
Dave Horsfall wrote in <alpine.BSF.2.21.9999.2303131331350.67613@aneurin.horsfall.org>: |[ Followups to COFF, as this is rapidly becoming a Unix tutorial ] .. |On Sun, 12 Mar 2023, Steffen Nurpmeso wrote: ... |> Even on a x86(-32) i have gnashed with my teeth. And that with ... |You can read X86 assembler? I can only do that after a few stiff Unfortunately i stopped my ambitions (nasm was non-portable but fun). I never stepped to ARM, i hate that, i read according Net and FreeBSD commits with lots of interest. Many years ago there was a thrilling commit series for string and memory ops on NetBSD that i sometimes still speak of ... Matt Thomas i think it was. ("Thrilling" it was for me; by then.) |drinks... I did buy the book (in order to debug a floating bug defect |in the optimiser -- hey, let's optimise this instruction right out! -- and But floating-point i run away. |I've never trusted optimisers since). | |[*] |Cue the saying about it being impossible to design a foolproof system. | |-- Dave, the iconoclast "Dawn Of The Iconoclast"; Lisa Gerrard is also an Aussie and nuclear she is, isn't she. (Shown with unforgotten Klaus Schulze at the Loreley -- since most of the UNIX beards are surely some kind of long haired beauties this could even go to TUHS.) Yeah, signals, no. Problems anywhere. But i have a command PKILL_TMUX "pkill -CONT tmux" in my ~/.cwmrc (when Linux sends ^Z to the wrong for whatever reason), and enough ptys to go to when ogg123 again gets an interruption wrong and hangs deadly, only killable via -KILL. I think setting a flag plus EINTR is a way, but ERESTART is not handable if you sit on something blocking but have to act upon the signal; message passing -- if you do have an event loop based program then this is nice; then again i woke up with horrors for the (first) Linux thread library (i have looked in) over twenty years ago, and they used a worker and serialization via such as a regular thing; also owed to Butenhof's POSIX thread design of course, which is too "free" in my eyes (i'd rather have a dedicated main thread plus workers); just like C++ exceptions (i saw software which "throws char*"). --End of <alpine.BSF.2.21.9999.2303131331350.67613@aneurin.horsfall.org> --steffen | |Der Kragenbaer, The moon bear, |der holt sich munter he cheerfully and one by one |einen nach dem anderen runter wa.ks himself off |(By Robert Gernhardt)