Linked by Thom Holwerda on Thu 7th Sep 2017 23:31 UTC
General Development

This release is the result of the community's work over the past six months, including: C++17 support, co-routines, improved optimizations, new compiler warnings, many bug fixes, and more.

The release notes contain more details.

Order by: Score:
Stackless coroutines
by kwan_e on Fri 8th Sep 2017 05:23 UTC
kwan_e
Member since:
2007-02-18

I'm a bit disappointed that we're going to be stuck with stackless coroutines. You have to wonder what's the point of having billions of coroutines if you can't suspend at a deeper stack level.

Reply Score: 3

RE: Stackless coroutines
by Megol on Fri 8th Sep 2017 12:33 UTC in reply to "Stackless coroutines"
Megol Member since:
2011-04-11

I was surprised when I read that as LLVM can support almost any type of co-routines given that it is a pretty flexible design.

But then it became clear that LLVM is now released as a package together with CLANG. Yeah.

So if you don't like the C++ limitations use another language - problem solved. Or you could implement your own kind unless C++ is even more fucked up since I last looked at it.

Reply Score: 2

RE[2]: Stackless coroutines
by kwan_e on Fri 8th Sep 2017 13:19 UTC in reply to "RE: Stackless coroutines"
kwan_e Member since:
2007-02-18

So if you don't like the C++ limitations use another language - problem solved. Or you could implement your own kind unless C++ is even more fucked up since I last looked at it.


Not to worry, since Boost has stackful coroutines, and now fibers and channels that are implemented similarly to stackful coroutines. I've been using coroutines for async stuff and it works a treat, so C++ is not limited in that regard. It's just that stackful coroutines won't be standard or have a nicer syntax.

Reply Score: 3

RE[3]: Stackless coroutines
by FlyingJester on Fri 8th Sep 2017 19:59 UTC in reply to "RE[2]: Stackless coroutines"
FlyingJester Member since:
2016-05-11

But then you're using Boost, a poorly designed, poorly tested, poorly implemented, inconsistent, gigantic library, which tries to be robust but isn't, tries to be header-only but isn't, and goes to ridiculous lengths to smooth over what are, in reality, small differences between OSes.

Reply Score: 1

RE[4]: Stackless coroutines
by fretinator on Fri 8th Sep 2017 21:03 UTC in reply to "RE[3]: Stackless coroutines"
fretinator Member since:
2005-07-06

Opinion much?

Reply Score: 4

RE[4]: Stackless coroutines
by kwan_e on Fri 8th Sep 2017 23:50 UTC in reply to "RE[3]: Stackless coroutines"
kwan_e Member since:
2007-02-18

a poorly designed


By some standards. Some people prefer Java style OO libraries, for which there is POCO and Qt. But those are for people who are incapable of learning anything outside of the OO style they emulate while at university that they mistake for good design.

Boost libraries can be over engineered, but that's because they were mostly designed when it was needed to support C++03. No other library for any other language has made similar efforts to be backwards compatible (and still has the same performance characteristics as C++).

poorly tested


Only for the compiler/architecture combination for which test boxes are hard to come by.

poorly implemented, inconsistent,


The stuff that made into the standard are not poorly implemented, but they were unable to take advantage of new language features because of the different times they became part of the next standard. Inconsistencies are to be found in every large library. Also different domains may be served better by different styles, so that kind of inconsistency only matters if you are unable to use anything that's not purely OO, or that's not purely template magic, or that's not purely functional, depending on your limitations of understand. Good programmers don't have trouble switching between them when the problem space requires it.

gigantic library


Some say it's too big. Some say it's not big enough.

which tries to be robust but isn't,


No, what it's trying to be is as a testing ground for things that may go into the standard library or language.

tries to be header-only but isn't


There's no mandate that libraries have to be header only. These design choices are left up to library author. So there's no "trying" because it isn't Boost's aim to begin with.

and goes to ridiculous lengths to smooth over what are, in reality, small differences between OSes.


No. Most of the "ridiculous lengths" is to implement things that run across a vast number of compilers at different standards compliance levels, which happen to be across different OSes. The difference between these platform specific compilers can be huge.

Reply Score: 5

RE: Stackless coroutines
by Alfman on Fri 8th Sep 2017 12:36 UTC in reply to "Stackless coroutines"
Alfman Member since:
2011-01-28

kwan_e,

I'm a bit disappointed that we're going to be stuck with stackless coroutines. You have to wonder what's the point of having billions of coroutines if you can't suspend at a deeper stack level.


Well, if it gives you a problem, you can always fix it by forking it by yourself ;)


...ok, this CS joke didn't exactly warrant a post, but there it is, haha.

On a serious note, I haven't looked into it yet but it seems like that would make this feature highly incompatible with other core C++ features like template metaprogramming and even trivial accessor functions to provide OOP encapsulation ;)

Reply Score: 2

RE[2]: Stackless coroutines
by kwan_e on Fri 8th Sep 2017 13:26 UTC in reply to "RE: Stackless coroutines"
kwan_e Member since:
2007-02-18

On a serious note, I haven't looked into it yet but it seems like that would make this feature highly incompatible with other core C++ features like template metaprogramming and even trivial accessor functions to provide OOP encapsulation ;)


Coroutines are pretty powerful, even if they are stackless: https://www.youtube.com/watch?v=EVGenON6p9g , and they don't conflict with templates or OOP at all. Enhances* it, really, since the details of async don't need to leak out of a function, let alone an object.

The stackless thing just means if you want to have a lot of suspend points in your coroutine, they have to occur at the base stack frame, making them not composable.

Depending on your way of thinking, it could be a good thing. Some people hate things that are too powerful/new/unfamiliar and would prefer crippled implementations of things.

* "Enhances? Fancy word for a sellcode"

Reply Score: 2

RE[3]: Stackless coroutines
by Alfman on Fri 8th Sep 2017 14:46 UTC in reply to "RE[2]: Stackless coroutines"
Alfman Member since:
2011-01-28

kwan_e,

Coroutines are pretty powerful, even if they are stackless: https://www.youtube.com/watch?v=EVGenON6p9g , and they don't conflict with templates or OOP at all. Enhances* it, really, since the details of async don't need to leak out of a function, let alone an object.

The stackless thing just means if you want to have a lot of suspend points in your coroutine, they have to occur at the base stack frame, making them not composable.


I already know what they are, my point was merely that this makes it mutually exclusive with C++ features that require a stack frame.


Depending on your way of thinking, it could be a good thing. Some people hate things that are too powerful/new/unfamiliar and would prefer crippled implementations of things.


Sounds political ;)

Reply Score: 2

RE[4]: Stackless coroutines
by kwan_e on Fri 8th Sep 2017 15:15 UTC in reply to "RE[3]: Stackless coroutines"
kwan_e Member since:
2007-02-18

I already know what they are, my point was merely that this makes it mutually exclusive with C++ features that require a stack frame.


Only, like I said, if you want to suspend a coroutine in a nested stack frame. Stackless means it doesn't have its own stack, not that it doesn't use a stack. As I understand it, it uses the "main stack" when it is resumed. Between two "co_yield"s, it can use all the stack it likes. When it arrives at the next co_yield at the base stack level, the function's state is saved, and another coroutine (or the main function) takes its place.

This just makes these style of coroutines non-composable in the way that stackful coroutines are (eg, cooperative, program controlled, multitasking).

Edited 2017-09-08 15:16 UTC

Reply Score: 3

RE[5]: Stackless coroutines
by Alfman on Fri 8th Sep 2017 16:49 UTC in reply to "RE[4]: Stackless coroutines"
Alfman Member since:
2011-01-28

Only, like I said, if you want to suspend a coroutine in a nested stack frame. Stackless means it doesn't have its own stack, not that it doesn't use a stack. As I understand it, it uses the "main stack" when it is resumed. Between two "co_yield"s, it can use all the stack it likes. When it arrives at the next co_yield at the base stack level, the function's state is saved, and another coroutine (or the main function) takes its place.


Yes obviously it uses a stack, this paper outlines two classes of coroutines, those that support normal stack frames and those that do not.

http://cpp.mimuw.edu.pl/files/await-yield-c++-coroutines.pdf

I suspect the boost implementation allocates a full stack for each coroutine, in which case it would share the same memory overhead as threads, but without the overhead of context switching.

Stackless technically also allocates a stack, however it only allocates memory for a single stack frame. As with traditional event oriented programming, this is very compact compared with threads.

In theory a hybrid approach would be possible such that a coroutine could effectively yield from within recursive calls so long as the caller declared it's intentions to be yieldable, however it would seem that they didn't implement this in C++.

Reply Score: 3

RE[6]: Stackless coroutines
by kwan_e on Fri 8th Sep 2017 17:31 UTC in reply to "RE[5]: Stackless coroutines"
kwan_e Member since:
2007-02-18

I suspect the boost implementation allocates a full stack for each coroutine, in which case it would share the same memory overhead as threads, but without the overhead of context switching.


The Boost implementation allows you to set the size of the coroutine stack. If the compiler supports segmented stacks (such as gcc), you can specify a coroutine to use a custom allocator for segmented stacks to allow the stack to grow as needed.

In theory a hybrid approach would be possible such that a coroutine could effectively yield from within recursive calls so long as the caller declared it's intentions to be yieldable, however it would seem that they didn't implement this in C++.


I think there was a proposal that would just have the compiler analyze and decide whether to use stackful or stackless but it probably didn't make it in time.* But from what I've read, there hasn't been a successful attempt to emulate stackful coroutines with stackless.

* http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4398.pdf

Reply Score: 3

RE[7]: Stackless coroutines
by Alfman on Fri 8th Sep 2017 18:40 UTC in reply to "RE[6]: Stackless coroutines"
Alfman Member since:
2011-01-28

kwan_e,

The Boost implementation allows you to set the size of the coroutine stack. If the compiler supports segmented stacks (such as gcc), you can specify a coroutine to use a custom allocator for segmented stacks to allow the stack to grow as needed.



I think it's almost identical to the threaded case, minus the SMP concurrency.


I think there was a proposal that would just have the compiler analyze and decide whether to use stackful or stackless but it probably didn't make it in time.



This fits into the class of problems where the compiler can't know ahead of time whether something might happen before it runs. C implementations don't generally do intraprocedural code analysis, which is why C suffers from pointer aliasing and programmers have to explicitly set a flag to indicate their intent.


But from what I've read, there hasn't been a successful attempt to emulate stackful coroutines with stackless.


I don't really know if anyone's implemented it under a real compiler, but it's actually pretty straitforward in principal. While stacks are normally linear structures, there's no technical reason that they have to be. A trivial implementation would take each and every stack frame from the heap rather than a linear stack.

Pascal supports parent variable scoping, which may depend on having a linear stack, but C doesn't support this, they only way to access the variables of a caller is for them to be passed in through a pointer, which makes the relationship between stack frames irrelevant.

The implementation of C++ exceptions would have to change, but it would just have to walk the stack frames via pointers rather than manipulating address offsets.

This would work transparently to the code. However due to overhead costs we probably wouldn't want to use it globally. This is why I thought it would be good to allow the programmer to request it explicitly.

Edited 2017-09-08 18:42 UTC

Reply Score: 3