Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
C++ Stackless Coroutine (github.com/jbandela)
92 points by adamnemecek on April 28, 2016 | hide | past | favorite | 27 comments


Post-C++ 11 code is so very different from pre-C++ 11. Things are so different that I cannot even understand many of the constructs anymore. I realize C++11 is 5 years old now but still. I fear the same thing might happen to javascript as well with the changes in es7. I don't think this is a good thing for languages to change so much that the style becomes very different. This is probably the reason why developers like Go. The language designers are reluctant to change it from the get go.


C++11 is in a state right now where it is essentially unchallenged. It runs natively, has no garbage collection, zero cost abstractions, automatic memory management (memory leaks don't cross my mind any more) and most importantly, a hugely mature ecosystem.

C++11 on up is nothing short of revolution in systems programming. Hopefully D and Rust will be there eventually but right now no other language even comes close to the maturity of having 4 compilers you could bet your business on and just as many IDEs.


I think you're understating the case for Rust.

Rust has a better standard library (e.g., std::option) and better resource abstractions.

The "existing code" advantage seems a weak case at best for C++, given that it doesn't even have a package manager to use the code. Including 3rd party code is nightmarish.

A greenfield project would have to think long and hard about taking on the enormous bloat and not-for-mortals specifications of C++ over Rust.


I also think that Rust has a bright future ahead, but C++ will probably live forever. There is a huge amount legacy code in C++, a lot of it tied to embedded systems that have service contracts that measure decades.

C++ didn't manage to displace C completely, I doubt that Rust will manage to displace C++. This is especially true now that C++ is seeing active improvement that makes it a lot more attractive for new projects.


While true, I think the rise of Linux and FOSS, alongside embedded development helped C stay around.

On Mac OS, Windows, Symbian, BeOS, even commercial UNIX with CORBA and Motif OO libraries, developers were already transitioning from C to C++ when Linux and FOSS, which depend heavily on C, started to gain adoption.

Then you have the embedded space, specially with micro-controlers, where even packing C into the EPROM is already an exercise.

As for C++, the new standards rely reinvigorated it, with Apple, Google and Microsoft pushing it forward.

One of the reasons I updated to Windows 8 (now on W10) was to be able to use C++/CX with XAML. Visual C++ finally catched up with C++ Builder in terms of RAD experience.

This where I see Rust still needs to grow. There are lots of use cases where Rust still does not provide an out-of-the-box solution vs C++ tooling does.


I'm not making a case for anything or talking about 'existing code'.

What I said was that the infrastructure is here right now. I hope Rust succeeds in the future but there is a very big difference between the tools available right now.


Memory management in C++ is not automatic. You have to choose between unique_ptr and shared_ptr (among others), and getting it wrong results in use after free, which can be exploitable. Not using weak_ptr in the right place results in memory leaks. And so forth.


If you make good use of move semantics and return value optimizations. you can avoid using pointers in many more cases in the first place.

Using pointers only where really needed reduces your risk of memory leaks.


While true, it only works if everyone plays ball.

What I learned in my C and C++ years of enterprise coding is that I want to stay away from those codebases.

C++ can be lovely when used in small teams of skilled developers that play by the rules.

On typical enterprise code, with various skill sets of developers that come and go, many from consulting companies, it can be a huge pain to maintain and track down memory corruption issues.


That's fine, but protecting you from other people doing ridiculous things isn't really the fault of modern C++ as it is possibly a feature of a GC language. I think there is utility in not letting people out of a sandbox if they can't handle it, but I also think the fact that C++11 has a stark path that should be used is different than the high wire act of C and older C++.


It is a fault of C++, because there are other systems programming languages also without GC, that aren't as memory corruption friendly as C and C++.

They achieve that by either being older than C, or never being copy-paste compatible with it.

This is the biggest drawback of C++, even modern C++. C compatibility was a good way to achieve adoption, but also what hinders the language in terms of safety.

It doesn't matter how many safety features the language has, you always have a few cowboys coders doing "C with C++ compiler" style.

In the majority of typical enterprises where code review and static analyzers are foreign words, you get into horrible code bases.

I like the language a lot, it is the language I liked most to use after Turbo Pascal, used to teach it to first year students and have a few jobs on my CV where I really enjoyed using it.

Nowadays I rather use it in personal projects as infrastructure language alongside other ones where I can easily follow modern practices, rather than on the job in codebases where developers come and go.


Those ridiculous things are things we find everyone does again and again, even in modern C++.

C++11 doesn't really add anything in the safety department over smart pointer code that you could write in earlier versions of C++.


Quite true, the only thing that C++11 does is make it part of the standard library and offer a few language features that make it more pleasant to the eye.

I was already using smart pointers with COM in 1998, but of course most of the third party libraries we depended on, did not.


You have to use references and iterators, which are just as dangerous.


That's great until you work with any third party libraries.


Third party libraries don't really interfere though, they can be used the same as always or wrapped up in a class that implements move semantics.


Pragmatically though I don't use either because they are wrapped up in data structures. With copy elision and move semantics memory basically does become automatic on a day to day basis.

When I am making my own data structures I basically use unique_ptr or just use std::vector directly.

I've used shared_ptr in one relatively exotic situation and no other time.

I'm actually not even sure what you mean when you say use after free - I rarely expose a naked pointer, and when I do the lifetime and ownership are pretty obvious.

I like Rust and I'm not trying to downplay its significance, but I think you are misjudging the reality of working in C++11 - memory leaks and use after free don't seem to be an issue to me after having done nothing but C++11 for three years.


> I'm actually not even sure what you mean when you say use after free - I rarely expose a naked pointer, and when I do the lifetime and ownership are pretty obvious.

Reference and iterator invalidation, usually.

> I think you are misjudging the reality of working in C++11 - memory leaks and use after free don't seem to be an issue to me after having done nothing but C++11 for three years.

It continues to be an issue for us and every other browser vendor, despite widespread adoption of C++11 throughout the codebase. Large C++ apps that are believed immune to UAF typically just haven't been the target of people actively looking for holes.



could this be easily done without using boost?


Author here. The library itself (stackless_coroutine.hpp) has no dependencies other than C++14, and you can easily use it in any C++14 project with any async library.

For writing an interesting example, I wanted to do an example of how the library can simplify async network code. A widely used async C++ library is Boost.Asio, so that is what I used for the example.

TLDR: The library itself has no dependency on Boost. Boost.Asio was just used for the example.


It's a good example. I'm really liking asio so far. However, I've been using the standalone version[1]. Maybe you could do the same with your library?

[1]: http://think-async.com/Asio/AsioStandalone


I am planning on overhauling the example to use that latest version of Asio standalone that is tracking the C++ Networking TS. That way it will be a simple matter of people changing asio to std::experimental::net on a compiler that implements the Networking TS.


Here's one I wrote with stacks:

    https://github.com/jaroslov/coro


Would it work the same using c++11 async stuff? That would make my day :)


I'm very looking forward to playing with this library. Thanks for making it!


Does this really "help" in anyone's design? I know some people despise callbacks, but I would much rather read callback-based code than this (looking at example.cpp).




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: