It's funny, we keep talking about GOTO and ignoring the C++ elephant in the room: exceptions. I personally LOVE exception, but again, only when used correctly.
Defer is useful for dealing with temporary stuff. e.g "sharedVar.Lock(); defer sharedVar.Unlock()". Not when you want an effect to persist past a function return. If for example you must return 3 open files from a function or none in case of error, don't use defer (in case the first 2 open succeeded and 3rd one failed).In many cases, if a function is fully successful, you don't want cleanup. You return the newly allocated memory / resource as well as the other allocations underpinning it. Whereas a defer would incorrectly clean it up, even on success leading to a dangling pointer.
So defer could be nice... but for it to be really useful, it would been to be a "cancellable defer". And that is rare in programming languages.
Can you count the number of "goto" in FreeBSD project?
14543 err
14159 out
7788 fail
5162 end
4774 done
3715 cleanup
3663 error
1707 bad
1016 Exit
766 failed
I'm a big fan of exceptions. And its often annoying that a lot of "safety" subsets always tend to think that the language is magically safer without them (sometimes it is but not always).It's funny, we keep talking about GOTO and ignoring the C++ elephant in the room: exceptions. I personally LOVE exception, but again, only when used correctly.
But why does every minor feature in C++ have to have a 33 page explanation?
C++ is the favored language of pedantic language laywers
IF (A, GT, B, CH); The details have been hidden, but then you have to tell it to use a Compare Halfword instruction, because the fields are halfwords. Now you are down in the details again. To me, it's like when pilots are flying a plane with the autopilot, and suddenly it has a problem and turns control back to the pilot. The pilots have not been paying attention, and now they have to fly the plane, and they don't have a good feel for where they are, or what has been going on. (BTW, I always felt that the macros ought to be able to figure out which compare instruction to use, based on how the fields were designed. )So am I. They allow writing code much more clearly, because correct error raising and handling becomes either very concise (just say throw Exception('foo bar wen wrong')), or even invisible (most functions don't need try/catch blocks, because most exceptions filter way up the stack).I'm a big fan of exceptions.
It's funny, we keep talking about GOTO and ignoring the C++ elephant in the room: exceptions. I personally LOVE exception, but again, only when used correctly.
1.2 nsec/call 1.2 user 0.0 sys: atoi
75.1 nsec/call 75.1 user 0.0 sys: snprintf
153.4 nsec/call 153.4 user 0.0 sys: snprintf_float
134.8 nsec/call 134.8 user 0.0 sys: fnmatch
20.1 nsec/call 20.1 user 0.0 sys: condvar_signal
15.7 nsec/call 15.7 user 0.0 sys: mutex_lock_unlock
6.0 nsec/call 6.0 user 0.0 sys: pthread_mutex_trylock
26.8 nsec/call 26.8 user 0.0 sys: gettimeofday
195.9 nsec/call 195.9 user 0.0 sys: strncpy
5.3 nsec/call 5.3 user 0.0 sys: strchr
216.1 nsec/call 15.5 user 201.8 sys: getrusage
90.7 nsec/call 23.1 user 67.1 sys: read
142.4 nsec/call 38.9 user 103.5 sys: read1bdevzero
241.8 nsec/call 32.9 user 208.9 sys: read8kdevzero
56.9 usec/call 298.4 user 56554.5 sys: read2mdevzero
4.1 nsec/call 4.1 user 0.0 sys: rand
2.7 nsec/call 2.7 user 0.0 sys: random
5.1 nsec/call 5.1 user 0.0 sys: floatrand
5729.5 nsec/call 5720.0 user 0.0 sys: cpp_testhrow_throw_48
5362.4 nsec/call 5373.1 user 0.0 sys: cpp_testhrow_throw_24
5244.3 nsec/call 5236.3 user 0.0 sys: cpp_testhrow_throw_12
5100.3 nsec/call 5094.5 user 0.0 sys: cpp_testhrow_throw_4
5055.9 nsec/call 5063.4 user 0.0 sys: cpp_testhrow_throw
6.0 nsec/call 6.0 user 0.0 sys: cpp_testhrow_no_throw
4.8 nsec/call 4.8 user 0.0 sys: cpp_testhrow_no_possible_throw
2.2 nsec/call 2.2 user 0.0 sys: cpp_testhrow_no_cleanup_no_throw
1.2 nsec/call 1.2 user 0.0 sys: cpp_testhrow_no_cleanup_no_possible_throw
I'm not sure how common knowledge it is, but Stroutrup himself defined exceptions as "just another generic mechanism of program execution", not for the explicit and exclusive use of catching errors/exceptions. It seems that the restrictions on their more generic use has grown out of several generations of "best practices".That said, I have seen some crappy parsers throw exceptions as part of their normal success flow or to escape nested loops. That stuff is pretty gross!
Well, I mean that does make sense, and is expected, if you are thinking like a full stack computer scientist. Of course exceptions are going to be "expensive"Just don't use exceptions for regular flow control. Apart from bad style it is also horribly slow to actually throw exceptions (as opposed to just setting them up). This is also unique to C++, the fact that unthrown exceptions are very fast.
Agreed. The C++ community tends to be extremely noisy, with ideas pulling in so many different directions. The language is so (overly)complex these days, maybe it *does* need every feature to be painstakingly considered? I have a little talk here that I am potentially quite terrified of the questions. I have spoken at software engineering conferences but never a C++ focused one.
Well, I mean that does make sense, and is expected, if you are thinking like a full stack computer scientist. Of course exceptions are going to be "expensive"
Interesting. I recall in one of his books(?) he mentioned that using an exception to escape a deeply nested loop was "cute" but then went on to discuss other approaches to doing so. I have no idea which though... It was certainly an earlier one.I'm not sure how common knowledge it is, but Stroutrup himself defined exceptions as "just another generic mechanism of program execution", not for the explicit and exclusive use of catching errors/exceptions. It seems that the restrictions on their more generic use has grown out of several generations of "best practices".
There are Universities that begin / began with a functional languages.hus is the shame. It goes to how they teach computer science these days.
Dijkstra was all about putting more rigor into programming. Harlan D. Mills, too. The current trend of vibe coding would have driven them nuts.The reason dijkstra didn't like goto is because it makes formal verification very difficult, not because goto is inherently evil.
Well, no. Quite the opposite.Programming in Fortran all day sounds like a kind of punishment.
Gone are the times you had to make the arrays "big enough". Starting with Fortran 90, arrays of any rank can be allocatable. Not only that, but they are also automatically deallocated when out of scope (same for pointer arrays). No need to manually deallocate dynamically allocated arrays, unless they are defined in the main program.I had once the chance to work with Fortran on a Cray, and the debugger was absolute gold. Old f77 and before were really constrained when it came to flexibility, as there was no dynamic memory to have. You just make the arrays big enough. How it is today? I would need to check.
In the '70s, there was a civil engineering package called COGO ("COördinate GeOmetry"). In order to do large, dynamically allocatable storage, it took advantage of a quirk of the IBM FORTRAN E compiler. In the compiled code, there was one register that always pointed to the COMMON area. By defining a small COMMON area, then having an assembler subroutine that allocated a huge area of storage and put it address in the register, they could have as much storage as they wanted.Gone are the times you had to make the arrays "big enough".
not often that we see someone properly using the diaeresis!COGO ("COördinate GeOmetry").
When I was growing up in the sixties, it was common to see a diaeresis in words like coördinate, coöperate, and reëntrant. These days The New Yorker is about the only mainstream publication that still uses them. I think they perform a useful service, so I continue to use them. (I am pretty sure that were it not for the diaeresis, I would have grown up pronouncing reëntrant as reen-trant.)not often that we see someone properly using the diaeresis!