[HN Gopher] C++20 coroutines: "The bug is in the C++ standard, n...
___________________________________________________________________
C++20 coroutines: "The bug is in the C++ standard, not GCC."
Author : flykespice
Score : 114 points
Date : 2022-10-04 18:14 UTC (4 hours ago)
(HTM) web link (gcc.gnu.org)
(TXT) w3m dump (gcc.gnu.org)
| somerando7 wrote:
| You have to use something similar to
| https://github.com/facebook/folly/tree/main/folly/experiment...
| to solve this problem.
|
| It's a nasty bug that everyone encounters when first working with
| coroutines. (Similarly everyone will encounter references that
| don't live until you co_await the task).
| grogers wrote:
| Alternatively, you can pass the things you would have captured
| instead as arguments to the lambda (by value!) and they are
| valid for the duration of the coroutine. So you can do a lambda
| returning a coroutine lambda like task<Foo> t =
| [foo]() { return [](auto f) -> task<Foo> {
| co_await something(); co_return f; }(foo);
| }();
| boundchecked wrote:
| C++20 coroutines demonstrated one side of committee-led modern
| C++ that left an impression of it is ultimately designed-by and
| -for library writers; instead of being suggested third-party
| library or "wait for C++23" for better experience, I'd love to
| see these related machinery released the same time in the
| standard library.
| rwmj wrote:
| This is from Avi Kivity who added KVM (virt) support to the Linux
| kernel.
| scatters wrote:
| This is fixed in C++23 by adding explicit object parameters to
| the member function (and lambda) syntax:
| [x](this auto) -> future<T> { co_await something();
| co_return x; }
|
| The lambda capture is copied into the coroutine frame on launch,
| meaning that it won't dangle.
| jmt_ wrote:
| I would have never recognized this syntax as modern day C++
| without being told. The language has evolved so much in the
| last 30+ years that I don't know how anyone is able to keep up
| unless they've been doing it for decades. As a junior dev, C++
| scares the hell out of me - I'd rather wrestle with C, footguns
| and all, than wrestle with the foot-semiautomatic-rifles C++
| provides.
| sitzkrieg wrote:
| this looks so far and away from C++ of ye old its kinda funny.
| you could pass that as some new language
| MathMonkeyMan wrote:
| future<c++>
| jcelerier wrote:
| > you could pass that as some new language
|
| ...why would you think that a new standard isn't a new
| language?
| ijlx wrote:
| I mean, between consecutive standard releases not as much
| changes; it's pretty clear that they're the same language
| with some slight differences/new features. I think the
| point is C++ has had so much change over the years it
| almost seems unrecognizable compared to its earlier forms.
|
| Almost makes me think of the ship of Theseus. How do we
| define the point that it's so different it could be
| considered a different language? Backwards compatibility
| strikes me as a factor, but backwards compatibility is
| violated by languages all the time and it's still
| considered "the same language."
| olliej wrote:
| The bug report says that the lambda pointer is dangling and is
| leaked. I'm not at my computer atm so i can't tell which this is
| (by my definition dangling = security bug, leak = annoying, both
| are bad the former is obviously much worse), my intuition is that
| it's a dangling reference but not in a position to see codegen
| (I'd guess something similar occurs in clang if it's spec
| behaviour). Given that this is the obvious use case I feel that
| this would be worth fixing in the spec before widespread
| adoption.
|
| That all said it demonstrates the issues with a lot of new c++
| features, in that even today new features are added without real
| thought to memory safety. There were a couple of proposals to at
| least make it possible to specify lifetime constraints, even if
| they'd only be warnings initially, but they died because memory
| safety remains a lower priority than other sexier features.
|
| Like I really do love c++, but memory safety has to become higher
| priority than other features for a while.
| j-krieger wrote:
| > That all said it demonstrates the issues with a lot of new
| c++ features, in that even today new features are added without
| real thought to memory safety
|
| I would go much further than that and claim that there are new
| C++ features added without real thought to _other features_.
| The C++ feature list is so incredibly vast that language
| maintainers / spec writers would need to know every little
| intricacy of other features to assert that a combination would
| still produce correct output.
| asveikau wrote:
| We're now 11 years from c++11, but I wanted to say lambdas
| are generally well thought out with respect to how memory
| management works in c++. The syntax for captures is weird at
| first, but once you appreciate that what it's doing is
| playing nice with copy constructors, it's good.
| AlotOfReading wrote:
| The problem is so much worse than that. Combining even the
| most fundamental features of the language (like UB and
| concurrency) leads to dark corners where even experts like
| Boehm aren't sure. The recent TR about safety-critical C++ is
| basically "don't use C++", which is correct, but not
| particularly helpful.
|
| The reality is that the standard simply isn't a good enough
| reference for what the language does. If you care about that,
| you need to treat programming in it as an experimental
| endeavor where you validate that your particular combination
| of code + toolchain + hardware does what you want. It's nice
| if the standard goes along for the ride, but not something
| you can rely on.
| notacoward wrote:
| This is what _always_ seems to happen when systems only grow
| and never shrink. Later-added features don 't always play well
| with each other, even when they're added sequentially and it
| seems like they should. It's technical debt at the
| specification level (as opposed to code) and I've seen it bite
| more projects than I can count.
|
| Sometimes you just have to start swinging the axe, or else stop
| wasting effort and plan migration to an alternative. In this
| case the alternative seems to be Rust, and no, I'm not a Rust
| advocate. Far from it, in fact. Personally I find Zig and
| several others more appealing. However, I also feel that the
| state of the art will advance more quickly if the C++
| programmers migrate to _any_ of those alternatives, and Rust
| seems pretty far ahead as the direct successor.
| masklinn wrote:
| In fairness, features which break one another are not a new
| thing in C++.
|
| > they died because memory safety remains a lower priority than
| other sexier features.
|
| Is it a priority at all? Or is it on a list titled "!" under a
| cabinet in the disused toilets of the third basement?
|
| I don't know whether 20 did as well, but C++17 literally added
| explicitely anti-memory-safety features (std::optional).
| kllrnohj wrote:
| > but C++17 literally added explicitely anti-memory-safety
| features (std::optional)
|
| How did you reach the very odd conclusion that std::optional
| is "anti-memory-safe"?
| masklinn wrote:
| Because the committee took something which is normally a
| way to lift nullability into the type system and make
| pointers null-safe, and instead made it... a nullable
| pointer. With all the absence of safety of a C++ pointer.
| jcelerier wrote:
| > Because the committee took something which is normally
| a way to lift nullability into the type system and make
| pointers null-safe, and instead made it... a nullable
| pointer. With all the absence of safety of a C++ pointer.
|
| anything that adds a branch to check dereference in
| release builds is an instant no-go, what do you propose
| to do instead?
| pornel wrote:
| That "instant no-go" is the problem. C++ is still
| unwilling to budge even a tiniest bit for safety.
|
| In most scenarios there has to be a check _somewhere_.
| Where C++ got it wrong is allowing separation of the
| check from the use of the now-known-to-be-set value, so
| the necessity to have convenient zero-cost _unchecked_
| use is a problem C++ has created for itself.
|
| Safe languages solved this by carrying the checked state
| over using the type system (e.g. pattern matching or flow
| typing), so further the uses after the check are free AND
| guaranteed safe.
|
| There are some situations where the state of the optional
| being set is known from the context, but in a convoluted
| way too complex for the type system to follow. C++
| focused on supporting this case -- unwilling to
| compromise on either syntax or performance, and
| sacrificed safety for it.
|
| Other languages in such muddy scenario either take the
| cost of a branch or have an unchecked-unsafe function for
| optimization, but importantly -- that function doesn't
| get a syntax sugar. It is meant to stand out as a rare
| risky operation, and not be hidden behind super common
| innocent-looking syntax.
| CJefferson wrote:
| Why is it a no-go? If you mark the check as "unlikely"
| the cost is extremely small, and maybe we should just pay
| the cost rather than have undefined behaviour.
| jcelerier wrote:
| > the cost is extremely small
|
| until it isn't, i've seen branches eat 10-15% of hotspots
| sometimes. but honestly, in practical terms, I shouldn't
| complain if people want that: that's literally more
| consulting money in performance consulting for me
| afterwards :-)
|
| let me repost one of my own past comments with a quick
| and dirty benchmark:
| https://news.ycombinator.com/item?id=30867368
|
| I have been paid hard money for performance improvements
| _much smaller_ than something like this in my life
| kouteiheika wrote:
| > anything that adds a branch to check dereference in
| release builds is an instant no-go
|
| ...which, as shown by Rust, is actually not true, and is
| very much a go in the vast majority of cases.
|
| > what do you propose to do instead?
|
| It's easier and more natural to access the optional in an
| unsafe way (through the -> operator) than access it in
| the safe way (through `value()`); this is a wrong default
| which should have been made the other way around.
|
| Potentially unsafe behavior should be opt-in, instead of
| opt-out. Yes, it's important that you have the option to
| disable this check for performance-sensitive code. But
| the majority of the code is _not_ performance-sensitive
| to this degree that an extra branch is going to make any
| difference whatsoever.
| kllrnohj wrote:
| > It's easier and more natural to access the optional in
| an unsafe way (through the -> operator) than access it in
| the safe way (through `value()`); this is a wrong default
| which should have been made the other way around.
|
| Then it's inconsistent with std::vector & similar.
| Consistency across the standard library seems much more
| worthwhile, especially here where it's pretty obvious
| when you mess up using a std::optional (like just never
| checking if it has a value, which jumps out in code
| reviews quite clearly)
| kllrnohj wrote:
| std::optional is not limited to pointers, and it has the
| safety if you want it - use value().
| electroly wrote:
| There are some platforms that provide std::optional but
| not value()! macOS 10.13 is one of them. You're forced to
| use the unsafe * operator on that platform. I cannot
| imagine the rationale that went into shipping
| std::optional support without value(), but they did it.
| hvdijk wrote:
| std::optional can be described as memory-unsafe because
| indirection when an optional is empty has undefined
| behaviour rather than deterministically throwing an
| exception or aborting the program, and may misbehave in all
| sorts of spectacular ways, including accessing random
| memory, on common implementations. Thankfully,
| implementations can and do provide ways to get it to behave
| more predictably.
| kllrnohj wrote:
| But that's not actually true in general.
| std::optional<int> has no such indirection issues, for
| example.
|
| If you're saying that blindly calling `operator->` on a
| std::optional<int*> without ever checking has_value() or
| similar can result in dereferencing garbage then yes,
| sure? But calling that "explicitly memory-unsafe" seems
| misleading at best, and just aggressively wrong at worst.
| You can always use `value()` if you want an error-
| throwing option, just like std::vector has at(). The
| standard didn't just ignore that.
| spoiler wrote:
| I think the phrasing of "explicitly memory-unsafe" is
| wrong[1] in letter, but true in spirit. At the end of the
| day `std::optional<T>` is only _marginally_ better than
| `T*`. And I 'm sometimes not even sure if it's better or
| worse; the extra API surface you describe is nice, but in
| practice it's just a mirage of safety, since its API
| subset includes that of a common pointer. And I've seen
| ample code use the unsafe API because
| (convenience/performance/inexperience).
|
| But at the end of the day, I guess my comment is also
| irrelevant, because we as developers should strive for
| correctness, not brevity, in code. If we can achieve
| both, the better. But alas, brevity and correctness are
| in an antagonistic tension in C++. So when we want
| correctness in C++, we should also be prepared to swallow
| a large portion of spaghetti Bolognese.
|
| [1]: Or at least no more melodramatic than the phrase
| "aggressively wrong" lol
| kllrnohj wrote:
| > At the end of the day `std::optional<T>` is only
| marginally better than `T*`.
|
| It's dramatically better than `T*` if your data isn't a
| pointer in the first place.
| hvdijk wrote:
| Sure, std::optional<int> is unlikely to result in such
| behaviour in practice, and std::optional<int*> is likely
| to "only" result in such behaviour if the result of
| operator*() is dereferenced again, despite both already
| being UB. Think of non-POD types, such as
| std::optional<std::string>, though: when you end up using
| uninitialised std::string objects, things do break in
| practice because of pointers used internally to implement
| std::string, and badly so.
|
| The fact that checked versions exist but are not used by
| default, have to be explicitly opted into, is consistent
| with C++'s designs and may be used to defend the current
| design, but at the same time also means it describing
| std::optional as memory-unsafe becomes a valid opinion
| based on facts, I think.
| kllrnohj wrote:
| > but at the same time also means it describing
| std::optional as memory-unsafe becomes a valid opinion
| based on facts
|
| But your "facts" are "if I use the API wrong, it behaves
| wrong." But std::optional isn't easy to accidentally
| misuse here, unlike string_view (an actually "unsafe"
| addition). The argument that optional is broken if you
| both don't use has_value _and_ don 't use any of the
| other helpers (like value_or() or value() or transform or
| etc...) then it has UB means that optional is "broken by
| design" is not a very strong position to take.
|
| It's hard to imagine this being a problem in practice.
| It's pretty encoded in the code that it's optional, to
| just completely ignore that and blindly access it anyway
| seems pretty self-evident as a usage issue. Yes bugs
| happen, but come on. This is not a particularly sharp
| edge in C++'s toolbox here. It's a pretty
| straightforward, intuitive type, doing pretty much
| exactly what it says it does, exactly how you'd expect it
| to do.
|
| Should operator->() and value() be swapped? _maybe_ , but
| then it'd be inconsistent with std::vector & other older
| types. And that inconsistency is probably worse overall.
| hvdijk wrote:
| > But your "facts" are "if I use the API wrong, it
| behaves wrong."
|
| Kind of, yes. That is what memory safety is about, isn't
| it? If I look for definitions, I find for instance
| <https://hacks.mozilla.org/2019/01/fearless-security-
| memory-s...>, explaining it as:
|
| > When we talk about building secure applications, we
| often focus on memory safety. Informally, this means that
| in all possible executions of a program, there is no
| access to invalid memory. Violations include:
|
| > - use after free
|
| > - null pointer dereference
|
| > - using uninitialized memory
|
| > - double free
|
| > - buffer overflow
|
| std::optional does not itself protect against using
| uninitialised memory, it merely provides the tools by
| which the programmer can prevent using uninitialised
| memory. Isn't that exactly what memory safety is about,
| about having std::optional somehow automatically ensure
| that that doesn't happen? If that isn't what memory
| safety is, what, in your opinion, does it mean instead?
|
| Note that I have attempted to refrain from posting my
| opinion on whether C++ made the right call or not. That
| is a separate question from whether it qualifies as
| memory-safe.
| kllrnohj wrote:
| I'm not arguing that c++ is memory safe, it isn't. But
| the initial claim is that std::optional is "explicitely
| anti-memory-safety". And _that_ seems like a very
| unsupported claim. std::optional isn 't safer than the
| rest of C++, but it's definitely not _less safe_ either.
| hvdijk wrote:
| Ah, thanks for the clarification, I think we've been
| talking about two slightly different things, then. For
| you, std::optional would have to make C++ more memory-
| unsafe than it already is in order for "anti-memory-
| safety" to be a fair characterisation. For me, that label
| merely implies that memory-safer alternative designs of
| std::optional were considered, and the current design was
| picked despite its memory-unsafety being a known
| potential issue. I think I would likely agree with you
| that std::optional does not make C++ less memory-safe
| than it already was before that got added.
| jiripospisil wrote:
| The discussion continued over at "std-proposals"
| https://lists.isocpp.org/std-proposals/2020/05/index.php#msg...
| Ygg2 wrote:
| Needs 2020 tag.
| varelse wrote:
| j-krieger wrote:
| Putting the discussion about C++ memory safety and concurrency
| issues aside, I am pretty astonished that C++ continues to
| include bugs where you have two actual _language features_ - not
| library functions - which on their own work perfectly fine, but
| combining the two makes the entire thing silently implode.
|
| I am trying very hard to imagine any other higher level language
| where two distinct language features, each used correctly in
| their own way, can not be safely combined. The only thing that
| comes to mind are python's default parameters and passing an
| empty list as one.
|
| C offers total freedom in exchange for providing ways to shooting
| yourself in the foot. All of its "dangerous" features _can_ be
| used correctly for some benefit. With C++ it feels like to me
| like that benefit is often lost entirely, and whats left is just
| incorrect code that for some reason passes by the compiler
| without error.
| eloff wrote:
| I've always thought of C++ as the most complex programming
| language I know. With each revision it becomes more complex. I
| gave up and just moved on to Rust a year and a half ago. I have
| no regrets.
|
| C++ has not quite joined Perl, PHP, and Java as languages I
| will not work with anymore, but it's the next logical
| candidate.
| tasubotadas wrote:
| No idea why you decided to lump Java together with these
| abonimations.
|
| Java by itself is an extremely simple language.
| eloff wrote:
| In theory Java is not so bad. I just have never enjoyed
| working with it or with the code Java developers end up
| creating. Kotlin is reasonably pleasant. I've sometimes
| used it when the JVM was a hard requirement.
| marginalia_nu wrote:
| Java is like one of those ice berg memes with a lot of
| byzantine JVM shit lurking at the depths.
| bugfix-66 wrote:
| I used C++ full-time for more than a decade before finally
| abandoning it in disgust.
|
| Now I use Go for most purposes, and C or CUDA when
| appropriate.
|
| Good riddance.
| spoiler wrote:
| I've not worked with PHP for over 8 years now, but I hear
| it's gotten much better recently.
|
| It still has issues that are commonly associated with hosting
| provider configuration/control over the runtime, apparently.
|
| (sources are anecdotal; two friends who've had the mental
| fortitude to stick with the language for so long)
| jmt_ wrote:
| PHP 7 & 8 introduce lots of improvements. I used PHP 5 when
| I got into web dev and remember moving to Python as soon as
| I could. At work I've had to use PHP 7 and have been very
| pleasantly surprised at how solid it is. Now that I have
| more experience than my PHP 5 days, it's become apparent
| that PHP is very clearly suited for web work and the built-
| in functions offer many conveniences for such work that
| simply aren't available in other languages (granted other
| languages weren't built for web like PHP was). I've been
| surprised by my speed in PHP and I chalk most of that up to
| many helpful standard library functions. Even though PHP
| has a lot of old/compat functions still present I'm always
| surprised by how little that actually ends up effecting my
| productivity. So it's not my choice for greenfield projects
| but I'm not nearly as adverse to it now after working with
| modern day PHP for a bit.
| 0xbadcafebee wrote:
| I find it unreasonable that every language would have all of
| its features always compatible. Why can't we just say "don't
| use X and Y together" ? It might solve a ton of problems. All
| you have to do is have a big red warning in the manual that
| says _DON 'T COMBINE X AND Y_, and a language feature that lets
| you turn on X and turn off Y.
| CJefferson wrote:
| Who reads the "manual of C++" -- what even is that, the
| standard document (certainly no-one should read that for
| learning).
|
| It would be just about OK for the compiler to refuse to
| compile X and Y together.
|
| If you "switched off" X, then in C++ (where code is in
| headers which are just concatenated with your code), this
| would effectively split the language, as you also couldn't
| use libraries which use X in their headers.
| jejones3141 wrote:
| Orthogonality has been recognized as desirable at least since
| the days of Algol 68. Once you couldn't pass a struct as a
| parameter in C. Now you can.
| [deleted]
| j-krieger wrote:
| > Why can't we just say "don't use X and Y together"?
|
| Because that goes against the most fundamental idea of
| programming languages that you can build larger abstractions
| by combining basic building blocks.
| travisgriggs wrote:
| Abstractly speaking, what if we consider a "big ball of
| spaghetti" and "working program" to both be abstractions of
| just "a program". Now it fits under the larger abstraction
| umbrella still. :D
|
| All other things aside, C++ seems to be the language "to
| big to fail" and so it just keeps getting more and more
| features added to keep it competitive.
| [deleted]
| 0xbadcafebee wrote:
| A half dozen languages already do this and abstractions
| still work
| extropy wrote:
| Sure, here is your Lego set. But do not put while bricks next
| to red ones or it will explode!
| selimnairb wrote:
| I have returned to using C++ over the last six-months after not
| using it really since university 20+ years ago. I mostly write
| Python these days, Java in the past, but have also recently
| written some moderately complex and unsafe C (e.g., making a
| parser using flex and bison; doing lots of void* pointer
| arithmetic to get around not having runtime reflection). I am
| astonished at the complexity of modern C++. I've studied Rust
| and used some Swift (on an iOS app for a client a couple of
| years back), and I struggle to "correctly" write code in C++. I
| feel as if C++ is collapsing under its own weight.
| TremendousJudge wrote:
| Similar story here. I'm constantly wrestling with the tool
| more than the actual problem I should be solving
| curtis3389 wrote:
| I programmed in C++ all through college, and I get the same
| feeling watching its development.
|
| TR1 brought the language to a pretty good place with smart
| pointers, and at first C++11 looked awesome with its type
| inference features and range-based for loops.
|
| But, also in C++11 were tons of weird gotchas with new and
| old features. The one that comes to mind is the uniform
| initialization. It was supposed to fix the issues with
| calling regular constructors, so you could just use the new
| syntax and not worry.
|
| But, they also added initializer lists, and those have issues
| with uniform initialization, so now you not only need to know
| all the pre-existing issues with the old syntax, you need to
| know the new syntax and its issues.
|
| This all comes back to C++ refusing to break backwards
| compatibility, which is great and all, but at this point
| they've made a language that is only good for job security.
| synergy20 wrote:
| what exactly are them? I'm also back to modern c++ but I plan
| to only use a subset of the super set to make life easier.
| for example I don't need write a c++ library so many of the
| new (meta-template-programming) feature I don't need to pay
| attention to at least for now.
|
| what I really need are RAII, smart pointer, the STL library
| and algorithms basically, plus simple OOP use cases, those
| combined are not very complicated to me.
| masklinn wrote:
| > I am trying very hard to imagine any other higher level
| language where two distinct features, each used correctly in
| their own way, can not be safely combined. The only thing that
| comes to mind are python's default parameters and passing an
| empty list as one.
|
| And even then it's not a bug per-se, at best a misfeature (it
| can be useful as a performance hack although the performance
| improvements of global and builtins lookups of 3.11 might
| finally put that to rest).
| hellcow wrote:
| > I am trying very hard to imagine any other higher level
| language where two distinct language features, each used
| correctly in their own way, can not be safely combined.
|
| Handling JavaScript exceptions as opposed to promise rejections
| in async code is a continual source of pain. They don't work
| together. If you do try/catch on async code but forget to call
| await, catch will never be hit and your program might crash.
| There appears to be no linter available to detect this. Unless
| I've completely missed something, the interaction between these
| two features is a terrible design.
| avgcorrection wrote:
| There are two sorts of languages: languages with a coherent
| feature set and those that people actually use. Wait hold on,
| that doesn't apply here...
| kllrnohj wrote:
| > C offers total freedom in exchange for providing ways to
| shooting yourself in the foot. All of its "dangerous" features
| can be used correctly for some benefit.
|
| C is pretty archaic in its feature set, so it's not surprising
| it doesn't have many language features that don't work well
| together since it doesn't really have any language features in
| the first place. That's not necessarily a _good_ thing, either,
| but that 's a different discussion.
|
| > With C++ it feels like to me like that benefit is often lost
| entirely, and whats left is just incorrect code that for some
| reason passes by the compiler without error.
|
| That's an odd statement to make here. Yes this is an
| unfortunate combination that results in memory leaks, but how
| is C's "everything is a memory leak" any better? 100% broken is
| better than 10% broken?
|
| That said, I do wish C++ hadn't added coroutines in the first
| place. It feels like a weird addition to the language. Then
| again, I also wish Rust hadn't added them, either. They are
| nightmarishly complex in a non-GC'd language, and the benefits
| are far from clear. The "colored function" problem remains a
| hotly debated topic, and low-level, performance-focused
| languages (like C++ & Rust) feel like the very wrong place to
| hammer on those topics.
| j-krieger wrote:
| > That's an odd statement to make here. Yes this is an
| unfortunate combination that results in memory leaks, but how
| is C's "everything is a memory leak" any better? 100% broken
| is better than 10% broken?
|
| Because if you use features that may leak memory, you can
| still trust yourself as a programmer. If you cant even trust
| the language / compiler, I would consider that worse.
|
| > Then again, I also wish Rust hadn't added them, either
|
| I agree.
| dtgriscom wrote:
| > Yes this is an unfortunate combination that results in
| memory leaks, but how is C's "everything is a memory leak"
| any better? 100% broken is better than 10% broken?
|
| I'd rephrase "100% broken" as "always does what it says it
| will", and "10% broken" as " _almost_ always does what it
| says it will. " I'd prefer the former 99% of the time.
| notacoward wrote:
| > C's "everything is a memory leak" any better?
|
| That's a bit hyperbolic, unless you apply the same phrase to
| any language (including C++) without a full tracing garbage
| collector or equivalent. X leaking a resource is not the same
| as X returning a resource that the caller is explicitly
| responsible for freeing. Further, C _in practice_ is not as
| bad as you portray. Maintainers of large open-source
| projects, of which I used to be one, often define their own
| memory-management facilities and rules which are just as good
| as C++ 's in preventing leaks for most code. I think they
| shouldn't need to nowadays, and that C would be a poor choice
| for a new project at any level, but that's easily shown
| without resorting to hyperbole.
| dkackman11 wrote:
| Agree. Modern C++, and discussions around it, become more
| esoteric with every revision. As software engineers we should
| spend our time understanding the esoterica of the problem
| domain, not the toolset.
| hdjjhhvvhga wrote:
| I'm of the same opinion. Frankly, when Go first appeared, I
| felt we would finally get something almost as simple as
| Python and almost as fast as C. Unfortunately not everything
| was as nice as I had expected. Still, in that respect it's
| better than Rust as it makes it easier to focus on the
| problem rather than the language.
| xyzzy4747 wrote:
| I personally still don't understand the benefit of Go vs
| Java? They seem to accomplish similar things with similar
| amounts of boilerplate.
| tomohawk wrote:
| Having used both professionally (several years each), Go
| is massively simpler than Java, at least for the problems
| we tackle. We sometimes will get a new dev on the team
| from Javaland, and the biggest thing for them is
| unlearning all of unnecessary complexity. YMMV.
| _wldu wrote:
| The complexity of C++0x is one reason Go was created.
|
| _" For me, the reason I was enthusiastic about Go was just
| about the same time we were starting on Go, I read (or
| tried to read) the C++0x proposed standard. And that was
| the convincer for me."_ - Ken Thompson
|
| 17:45 mark here: https://www.youtube.com/watch?v=sln-
| gJaURzk
| [deleted]
___________________________________________________________________
(page generated 2022-10-04 23:01 UTC)