12 ms·
C++20 coroutines: “The bug is in the C++ standard, not GCC.” (2020)
- deleted 4y ago[deleted]
- olliej 4y agoThe 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.
- notacoward 4y agoThis 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.
- selfmodruntime 4y ago> 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.
- AlotOfReading 4y agoThe 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.
- asveikau 4y agoWe'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.
- gpderetta 4y agoYes, lambdas are by far one of the best things to come out of the last 20 years of C++ development. They work exactly as a C++ programmer would expect (i.e. they are equivalent to a manually written struct overloading operator()). Coroutines, IMHO not so much; they are extremely complex and feel half baked. The problem is that there was so much discussion around them, that it was either that or nothing for the next 10 years.
- masklinn 4y agoIn 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 4y ago> 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 4y agoBecause 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 4y ago> 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?
- CJefferson 4y agoWhy 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 4y ago
- frankjr 4y agoThe discussion continued over at "std-proposals" https://lists.isocpp.org/std-proposals/2020/05/index.php#msg1367 https://lists.isocpp.org/std-proposals/2020/05/index.php#msg...
- selfmodruntime 4y agoPutting 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.
- masklinn 4y ago> 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).
- avgcorrection 4y agoThere 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…
- 0xbadcafebee 4y agoI 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.
- selfmodruntime 4y ago
- scatters 4y agoThis 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.
- sitzkrieg 4y agothis looks so far and away from C++ of ye old its kinda funny. you could pass that as some new language
- MathMonkeyMan 4y agofuture<c++>
- jcelerier 4y ago> you could pass that as some new language ...why would you think that a new standard isn't a new language?
- ijlx 4y agoI 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."
- Rebelgecko 4y agoC++ seems to have more churn than most other languages. e.g. if you're familiar with C99, you can read through a C17 code base and not even realize you're looking at something different. Even going back to C89 it's not that different. Other than some fancy syntax like comments using //, not much has changed. Sure, the standard library might have threads.h now or whatever, but your code is going to use the same letters on the keyboard. There's similar to other languages I'm familiar, even across major revisions the operators and syntax doesn't change much.
- Ygg2 4y agoNeeds 2020 tag.
- varelse 4y ago
- somerando7 4y agoYou have to use something similar to https://github.com/facebook/folly/tree/main/folly/experimental/coro#lambdas 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).
- boundchecked 4y agoC++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.
- grogers 4y agoAlternatively, 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); }();
- rwmj 4y agoThis is from Avi Kivity who added KVM (virt) support to the Linux kernel.
- deleted 4y ago[deleted]
- globalreset 4y agoI really don't know why people insist on polishing this turd.