Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #399861 > unrolled thread
| Started by | fir <profesor.fir@gmail.com> |
|---|---|
| First post | 2026-06-10 13:53 +0200 |
| Last post | 2026-06-17 12:11 -0700 |
| Articles | 20 on this page of 100 — 12 participants |
Back to article view | Back to comp.lang.c
acquire + sleep + async fir <profesor.fir@gmail.com> - 2026-06-10 13:53 +0200
Re: acquire + sleep + async fir <profesor.fir@gmail.com> - 2026-06-10 16:03 +0200
Re: acquire + sleep + async Lawrence D’Oliveiro <ldo@nz.invalid> - 2026-06-11 04:40 +0000
Re: acquire + sleep + async Bonita Montero <Bonita.Montero@gmail.com> - 2026-06-11 07:20 +0200
Re: acquire + sleep + async Lawrence D’Oliveiro <ldo@nz.invalid> - 2026-06-11 06:28 +0000
Re: acquire + sleep + async Bonita Montero <Bonita.Montero@gmail.com> - 2026-06-11 09:21 +0200
Re: acquire + sleep + async Lawrence D’Oliveiro <ldo@nz.invalid> - 2026-06-11 07:45 +0000
Re: acquire + sleep + async "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2026-06-11 15:56 -0700
Re: acquire + sleep + async David Brown <david.brown@hesbynett.no> - 2026-06-11 09:52 +0200
Re: acquire + sleep + async Bonita Montero <Bonita.Montero@gmail.com> - 2026-06-11 10:28 +0200
Re: acquire + sleep + async fir <profesor.fir@gmail.com> - 2026-06-11 10:44 +0200
Re: acquire + sleep + async Bonita Montero <Bonita.Montero@gmail.com> - 2026-06-11 11:36 +0200
Re: acquire + sleep + async Lawrence D’Oliveiro <ldo@nz.invalid> - 2026-06-12 01:32 +0000
Re: acquire + sleep + async Bonita Montero <Bonita.Montero@gmail.com> - 2026-06-12 06:16 +0200
Re: acquire + sleep + async "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2026-06-11 21:19 -0700
Re: acquire + sleep + async Bonita Montero <Bonita.Montero@gmail.com> - 2026-06-12 13:15 +0200
Re: acquire + sleep + async "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2026-06-22 12:15 -0700
Re: acquire + sleep + async Lawrence D’Oliveiro <ldo@nz.invalid> - 2026-06-12 23:52 +0000
Re: acquire + sleep + async Bonita Montero <Bonita.Montero@gmail.com> - 2026-06-13 05:05 +0200
Re: acquire + sleep + async scott@slp53.sl.home (Scott Lurndal) - 2026-06-13 14:52 +0000
Re: acquire + sleep + async Lawrence D’Oliveiro <ldo@nz.invalid> - 2026-06-16 00:12 +0000
Re: acquire + sleep + async "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2026-06-16 12:22 -0700
Re: acquire + sleep + async Lawrence D’Oliveiro <ldo@nz.invalid> - 2026-06-17 03:09 +0000
Re: acquire + sleep + async "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2026-06-17 20:29 -0700
Re: acquire + sleep + async "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2026-06-17 20:30 -0700
Re: acquire + sleep + async Lawrence D’Oliveiro <ldo@nz.invalid> - 2026-06-18 04:11 +0000
Re: acquire + sleep + async "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2026-06-18 00:18 -0700
Re: acquire + sleep + async Lawrence D’Oliveiro <ldo@nz.invalid> - 2026-06-18 07:23 +0000
Re: acquire + sleep + async "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2026-06-23 11:47 -0700
Re: acquire + sleep + async Bonita Montero <Bonita.Montero@gmail.com> - 2026-06-18 18:23 +0200
Re: acquire + sleep + async "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2026-06-18 12:46 -0700
Re: acquire + sleep + async Lawrence D’Oliveiro <ldo@nz.invalid> - 2026-06-18 23:01 +0000
Re: acquire + sleep + async "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2026-06-19 13:34 -0700
Re: acquire + sleep + async Bonita Montero <Bonita.Montero@gmail.com> - 2026-06-20 11:47 +0200
Re: acquire + sleep + async Lawrence D’Oliveiro <ldo@nz.invalid> - 2026-06-20 22:41 +0000
Re: acquire + sleep + async Lawrence D’Oliveiro <ldo@nz.invalid> - 2026-06-20 23:29 +0000
Re: acquire + sleep + async Bonita Montero <Bonita.Montero@gmail.com> - 2026-06-21 09:06 +0200
Re: acquire + sleep + async Lawrence D’Oliveiro <ldo@nz.invalid> - 2026-06-21 07:50 +0000
Re: acquire + sleep + async David Brown <david.brown@hesbynett.no> - 2026-06-21 12:22 +0200
Re: acquire + sleep + async Bonita Montero <Bonita.Montero@gmail.com> - 2026-06-21 13:41 +0200
Re: acquire + sleep + async "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2026-06-11 16:01 -0700
Re: acquire + sleep + async Lawrence D’Oliveiro <ldo@nz.invalid> - 2026-06-12 01:33 +0000
Re: acquire + sleep + async "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2026-06-11 21:05 -0700
Re: acquire + sleep + async Lawrence D’Oliveiro <ldo@nz.invalid> - 2026-06-12 23:54 +0000
Re: acquire + sleep + async David Brown <david.brown@hesbynett.no> - 2026-06-11 13:39 +0200
Re: acquire + sleep + async Bonita Montero <Bonita.Montero@gmail.com> - 2026-06-11 16:44 +0200
Re: acquire + sleep + async "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2026-06-11 21:11 -0700
Re: acquire + sleep + async Lawrence D’Oliveiro <ldo@nz.invalid> - 2026-06-13 00:01 +0000
Re: acquire + sleep + async "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2026-06-13 13:46 -0700
Re: acquire + sleep + async Lawrence D’Oliveiro <ldo@nz.invalid> - 2026-06-14 00:32 +0000
Re: acquire + sleep + async "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2026-06-16 12:23 -0700
Re: acquire + sleep + async Lawrence D’Oliveiro <ldo@nz.invalid> - 2026-06-17 03:07 +0000
Re: acquire + sleep + async "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2026-06-18 12:47 -0700
Re: acquire + sleep + async "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2026-06-18 12:51 -0700
Re: acquire + sleep + async Lawrence D’Oliveiro <ldo@nz.invalid> - 2026-06-12 00:14 +0000
Re: acquire + sleep + async "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2026-06-11 21:16 -0700
Re: acquire + sleep + async fir <profesor.fir@gmail.com> - 2026-06-11 10:34 +0200
Re: acquire + sleep + async Bonita Montero <Bonita.Montero@gmail.com> - 2026-06-11 11:38 +0200
Re: acquire + sleep + async Lawrence D’Oliveiro <ldo@nz.invalid> - 2026-06-12 00:13 +0000
Co-routines (was Re: acquire + sleep + async) Janis Papanagnou <janis_papanagnou+ng@hotmail.com> - 2026-06-11 18:50 +0200
Re: Co-routines (was Re: acquire + sleep + async) David Brown <david.brown@hesbynett.no> - 2026-06-12 12:42 +0200
Re: Co-routines (was Re: acquire + sleep + async) Bonita Montero <Bonita.Montero@gmail.com> - 2026-06-12 13:18 +0200
Re: Co-routines (was Re: acquire + sleep + async) David Brown <david.brown@hesbynett.no> - 2026-06-12 13:59 +0200
Re: Co-routines (was Re: acquire + sleep + async) Michael S <already5chosen@yahoo.com> - 2026-06-12 18:42 +0300
Re: Co-routines (was Re: acquire + sleep + async) David Brown <david.brown@hesbynett.no> - 2026-06-12 18:20 +0200
Re: Co-routines (was Re: acquire + sleep + async) Bonita Montero <Bonita.Montero@gmail.com> - 2026-06-12 18:58 +0200
Re: Continuations (was Re: Coroutines) Lawrence D’Oliveiro <ldo@nz.invalid> - 2026-06-13 00:04 +0000
Re: Co-routines (was Re: acquire + sleep + async) Bart <bc@freeuk.com> - 2026-06-12 14:51 +0100
Re: Co-routines (was Re: acquire + sleep + async) David Brown <david.brown@hesbynett.no> - 2026-06-12 16:04 +0200
Re: Co-routines (was Re: acquire + sleep + async) Bart <bc@freeuk.com> - 2026-06-12 16:16 +0100
Re: Co-routines (was Re: acquire + sleep + async) David Brown <david.brown@hesbynett.no> - 2026-06-12 17:31 +0200
Re: Co-routines (was Re: acquire + sleep + async) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2026-06-12 13:48 -0700
Re: Co-routines (was Re: acquire + sleep + async) "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2026-06-13 14:13 -0700
Re: Co-routines (was Re: acquire + sleep + async) fir <profesor.fir@gmail.com> - 2026-06-12 16:25 +0200
Re: Co-routines (was Re: acquire + sleep + async) fir <profesor.fir@gmail.com> - 2026-06-12 16:28 +0200
Re: Co-routines (was Re: acquire + sleep + async) Janis Papanagnou <janis_papanagnou+ng@hotmail.com> - 2026-06-12 19:13 +0200
Re: Co-routines (was Re: acquire + sleep + async) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2026-06-12 13:45 -0700
Re: Co-routines (was Re: acquire + sleep + async) Bart <bc@freeuk.com> - 2026-06-13 01:03 +0100
Re: Co-routines (was Re: acquire + sleep + async) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2026-06-12 17:50 -0700
Re: Co-routines (was Re: acquire + sleep + async) Bart <bc@freeuk.com> - 2026-06-13 11:03 +0100
Re: Co-routines (was Re: acquire + sleep + async) tTh <tth@none.invalid> - 2026-06-13 12:14 +0200
Re: Co-routines (was Re: acquire + sleep + async) Janis Papanagnou <janis_papanagnou+ng@hotmail.com> - 2026-06-13 14:35 +0200
Re: Co-routines (was Re: acquire + sleep + async) Bart <bc@freeuk.com> - 2026-06-13 14:38 +0100
Re: Co-routines (was Re: acquire + sleep + async) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2026-06-13 16:46 -0700
Re: Co-routines (was Re: acquire + sleep + async) Bart <bc@freeuk.com> - 2026-06-14 01:25 +0100
Re: Co-routines (was Re: acquire + sleep + async) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2026-06-13 18:26 -0700
Re: Co-routines (was Re: acquire + sleep + async) Bart <bc@freeuk.com> - 2026-06-14 12:28 +0100
Re: Co-routines (was Re: acquire + sleep + async) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2026-06-14 15:01 -0700
Re: Co-routines (was Re: acquire + sleep + async) Janis Papanagnou <janis_papanagnou+ng@hotmail.com> - 2026-06-22 19:46 +0200
Re: Co-routines (was Re: acquire + sleep + async) scott@slp53.sl.home (Scott Lurndal) - 2026-06-22 21:24 +0000
Re: Co-routines (was Re: acquire + sleep + async) Janis Papanagnou <janis_papanagnou+ng@hotmail.com> - 2026-06-23 01:16 +0200
Re: Co-routines (was Re: acquire + sleep + async) Tim Rentsch <tr.17687@z991.linuxsc.com> - 2026-08-14 12:45 -0700
Re: Co-routines (was Re: acquire + sleep + async) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2026-06-13 03:48 -0700
Re: Co-routines (was Re: acquire + sleep + async) Tim Rentsch <tr.17687@z991.linuxsc.com> - 2026-06-21 18:22 -0700
Re: Co-routines (was Re: acquire + sleep + async) Janis Papanagnou <janis_papanagnou+ng@hotmail.com> - 2026-06-12 18:14 +0200
Re: acquire + sleep + async "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2026-06-11 14:18 -0700
Re: acquire + sleep + async Lawrence D’Oliveiro <ldo@nz.invalid> - 2026-06-12 00:12 +0000
Re: acquire + sleep + async "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2026-06-11 21:06 -0700
Re: acquire + sleep + async "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2026-06-16 12:25 -0700
Re: acquire + sleep + async "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2026-06-17 12:11 -0700
Page 4 of 5 — ← Prev page 1 2 3 [4] 5 Next page →
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2026-06-12 12:42 +0200 |
| Subject | Re: Co-routines (was Re: acquire + sleep + async) |
| Message-ID | <110gnqf$24301$1@dont-email.me> |
| In reply to | #399906 |
On 11/06/2026 18:50, Janis Papanagnou wrote: > On 2026-06-11 09:52, David Brown wrote: >> On 11/06/2026 09:21, Bonita Montero wrote: >>> Am 11.06.2026 um 08:28 schrieb Lawrence D’Oliveiro: >>>> On Thu, 11 Jun 2026 07:20:18 +0200, Bonita Montero wrote: >>> >>>>> There are no coroutines in C. >> >> There are no coroutines in the C standard. There are a wide variety >> of coroutine implementations in C, with different mixtures of >> features, limitations, efficiencies, portability and requirements. >> For coroutines, it is most definitely not the case that one solution >> fits all needs - having it part of a language or standard is not >> necessarily a good idea (though some language support can be helpful). > > Frankly, lately I haven't followed the evolution of C++ in general > or know anything of C++'s co-routines, or how they are integrated > in the language, what changes they need in the memory model, etc. > Neither do I know about accepted (quasi-standard?) C-libraries. > > Just flanging external libraries might not suffice (or may result > in clumsy solutions or inherent principal restrictions), though. > > Simula (the first OO language with classes, inheritance, etc.) has > also an inherent co-routine functionality that fits very well with > its other supported concepts; simulation and "living objects" (sort > of). Created objects may have code executed (their "life"), and may > temporarily detach themselves or resume other objects. Its builtin > and more powerful simulation features also rely on that underlying > co-routine functionality. > > I'd be curious about what "C" (or C++) actually provides when they > speak about co-routines (whether it's libraries or built-ins). C does not have any direct co-routine support in the language and standard library, other than setjmp/longjmp that can be used for implementation. A popular (relatively speaking) way to do stackless co-routines in C is basically macro wrappers around a switch statement. Your coroutine has a parameter that is used by the switch to jump to the current entry point. Your "await" and "yield" operations (macros) make a "case" label with a new entry point, and returns that from the function or passes it on to the next co-routine. Any local variables that you want to keep between invocations need to be manually saved i some way, such as inside a static or heap-allocated struct. The "Protothreads" implementation of this has been used on very small microcontrollers. More sophisticated solutions involve longjmp and setjmp, which are more flexible and do more automatically, but are quite a lot more costly in runtime speed (but still much lighter than OS threads). These libraries may be stackless or stackfull, with limited portability. C++20 gained stackless co-routines in the language, with keywords and standard library functions. Not all tools implement them, and while they can automate some parts of using co-routines, they also involve a lot of boiler-plate code and type mess, making them much uglier and more error prone than in languages with clearer support for co-routines (like Python or Go). > > >>>> Yes, C is getting left behind in this regard ... >>> >>> C hasn't been improved much since 1973. >> >> What an astoundingly ignorant claim. > > I certainly wouldn't call her claim ignorant; I think it depends on > the abstraction level one has, but also on the expectations, about > what's possible, and what one knows from other languages or areas. > > In the stone-age era a club might have been considered a good tool. > In 1973, C was very new and primitive, and was quickly followed by a number of diverging and inconsistent versions. K&R C, the language from "The C Programming Language", was a huge improvement and standardisation compared to 1973 C. ANSI C / C89 / C90 was another massive step forward, as was C99. To suggest that C hasn't improved much since 1973 is either totally ignorant of the history of the language, or a deliberate lie. I choose to give Bonita the benefit of the doubt and assume ignorance. > Being a very subjective matter I suggest to abandon that subtopic. > I had not intended to reply to Bonita here - replying to Bonita is seldom useful IME, especially in c.l.c. But I am happy to reply to your posts!
[toc] | [prev] | [next] | [standalone]
| From | Bonita Montero <Bonita.Montero@gmail.com> |
|---|---|
| Date | 2026-06-12 13:18 +0200 |
| Subject | Re: Co-routines (was Re: acquire + sleep + async) |
| Message-ID | <110gpt7$250f6$2@raubtier-asyl.eternal-september.org> |
| In reply to | #399964 |
Am 12.06.2026 um 12:42 schrieb David Brown: > More sophisticated solutions involve longjmp and setjmp, which are more > flexible and do more automatically, but are quite a lot more costly in > runtime speed (but still much lighter than OS threads). These libraries > may be stackless or stackfull, with limited portability. With setjmp() and longjmp() you can jump out of a function, but not back inside. > C++20 gained stackless co-routines in the language, with keywords and > standard library functions. Not all tools implement them, and while > they can automate some parts of using co-routines, they also involve a > lot of boiler-plate code and type mess, making them much uglier and more > error prone than in languages with clearer support for co-routines (like > Python or Go). The boilerplate code is < 50 lines; so not much.
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2026-06-12 13:59 +0200 |
| Subject | Re: Co-routines (was Re: acquire + sleep + async) |
| Message-ID | <110gsbb$24ih1$5@dont-email.me> |
| In reply to | #399968 |
On 12/06/2026 13:18, Bonita Montero wrote: > Am 12.06.2026 um 12:42 schrieb David Brown: > >> More sophisticated solutions involve longjmp and setjmp, which are >> more flexible and do more automatically, but are quite a lot more >> costly in runtime speed (but still much lighter than OS threads). >> These libraries may be stackless or stackfull, with limited portability. > > With setjmp() and longjmp() you can jump out of a function, > but not back inside. Of course you can jump back - longjmp() jumps to where you had previously called setjmp(), and you have a new setjmp() just before the longjmp() so that you can jump back. > >> C++20 gained stackless co-routines in the language, with keywords and >> standard library functions. Not all tools implement them, and while >> they can automate some parts of using co-routines, they also involve a >> lot of boiler-plate code and type mess, making them much uglier and >> more error prone than in languages with clearer support for co- >> routines (like Python or Go). > > The boilerplate code is < 50 lines; so not much. > The source boilerplate code overhead for Protothreads is about a tenth of that. The overhead for other C coroutine libraries (or coroutines in languages with real support) is basically nothing.
[toc] | [prev] | [next] | [standalone]
| From | Michael S <already5chosen@yahoo.com> |
|---|---|
| Date | 2026-06-12 18:42 +0300 |
| Subject | Re: Co-routines (was Re: acquire + sleep + async) |
| Message-ID | <20260612184202.0000712b@yahoo.com> |
| In reply to | #399975 |
On Fri, 12 Jun 2026 13:59:38 +0200 David Brown <david.brown@hesbynett.no> wrote: > On 12/06/2026 13:18, Bonita Montero wrote: > > Am 12.06.2026 um 12:42 schrieb David Brown: > > > >> More sophisticated solutions involve longjmp and setjmp, which are > >> more flexible and do more automatically, but are quite a lot more > >> costly in runtime speed (but still much lighter than OS threads). > >> These libraries may be stackless or stackfull, with limited > >> portability. > > > > With setjmp() and longjmp() you can jump out of a function, > > but not back inside. > > Of course you can jump back - longjmp() jumps to where you had > previously called setjmp(), and you have a new setjmp() just before > the longjmp() so that you can jump back. > > > > >> C++20 gained stackless co-routines in the language, with keywords > >> and standard library functions. Not all tools implement them, and > >> while they can automate some parts of using co-routines, they also > >> involve a lot of boiler-plate code and type mess, making them much > >> uglier and more error prone than in languages with clearer support > >> for co- routines (like Python or Go). > > > > The boilerplate code is < 50 lines; so not much. > > > > The source boilerplate code overhead for Protothreads is about a > tenth of that. The overhead for other C coroutine libraries (or > coroutines in languages with real support) is basically nothing. > Big part of inconvenience of C++ co-routines is because of need to support constructors, destructors, including virtual ones and, worst of all, exceptions. C has none of those, so potentially similar stackless co-routines could have been added more naturally. But there is one critical part of the puzzle lacking - C++ style co-routines depend on heap. In C++ heap is a part of the core language, so there are no difficulties. In C, on the other hand, heap management belongs to Standard Library rather than to core language. In free-standing C implementation heap management can be completely absent. Last year I tried (not vary hard) to find solution to that problem, but language design is not really my cup of tee, so I was unable to invent anything satisfactory. At the end I came to conclusion, that for sort of jobs (in memory constrained embedded environment) where I would not mind having stackless co-routines, they are not necessarily the best technical solution. It's quite possible that normal co-routines, a.k.a. fibers, are better solution. And fibers don't have to be part of core language or even of Standard Library. However, fibers have one problem for which I would prefer language support - sometimes, when running in slim fiber, I want to call a "heavy" function, like sprintf or such, sort of function that in worst case needs a lot of stack space. Today in such case I have to provide a space for such function on stack of each and any fiber that can potentially use it. If I have dozens of fibers, that would be quite a lot wasted memory - instead of ~200 byte per fiber, or may be even less, I'd have to allocate few KB. That's where enhancement in core language code be handy - I want an ability to call a function not at current stack, but on some sort of common stack, shared by all fibers of the program. Or in case of multithreaded program, shared by all fibers of particular thread. Of course, in theory that sort of trampoline call/return could be implemented as a 3rd party library function as well, but somehow I fill that it belongs to language, at least as much as setjmp/lonjmp belongs to it, but preferably even in more integrated manner,
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2026-06-12 18:20 +0200 |
| Subject | Re: Co-routines (was Re: acquire + sleep + async) |
| Message-ID | <110hbkp$2ajup$1@dont-email.me> |
| In reply to | #399992 |
On 12/06/2026 17:42, Michael S wrote: > On Fri, 12 Jun 2026 13:59:38 +0200 > David Brown <david.brown@hesbynett.no> wrote: > >> On 12/06/2026 13:18, Bonita Montero wrote: >>> Am 12.06.2026 um 12:42 schrieb David Brown: >>> >>>> More sophisticated solutions involve longjmp and setjmp, which are >>>> more flexible and do more automatically, but are quite a lot more >>>> costly in runtime speed (but still much lighter than OS threads). >>>> These libraries may be stackless or stackfull, with limited >>>> portability. >>> >>> With setjmp() and longjmp() you can jump out of a function, >>> but not back inside. >> >> Of course you can jump back - longjmp() jumps to where you had >> previously called setjmp(), and you have a new setjmp() just before >> the longjmp() so that you can jump back. >> >>> >>>> C++20 gained stackless co-routines in the language, with keywords >>>> and standard library functions. Not all tools implement them, and >>>> while they can automate some parts of using co-routines, they also >>>> involve a lot of boiler-plate code and type mess, making them much >>>> uglier and more error prone than in languages with clearer support >>>> for co- routines (like Python or Go). >>> >>> The boilerplate code is < 50 lines; so not much. >>> >> >> The source boilerplate code overhead for Protothreads is about a >> tenth of that. The overhead for other C coroutine libraries (or >> coroutines in languages with real support) is basically nothing. >> > > Big part of inconvenience of C++ co-routines is because of need to > support constructors, destructors, including virtual ones and, worst > of all, exceptions. Good point, thanks. > C has none of those, so potentially similar stackless co-routines could > have been added more naturally. But there is one critical part of the > puzzle lacking - C++ style co-routines depend on heap. Heap-allocated storage is sometimes used with coroutines in C too, but the user has the choice. With Protothreads, you need to put your local variables somewhere if you want them to retain values across calls - typically you hold them in a struct. You choose if that is a static struct - fast, reliable, but not re-entrant - or in a heap allocation to allow re-entrant functions. I believe C++ coroutines always put the local frame on the heap. > In C++ heap is a > part of the core language, so there are no difficulties. In C, on the > other hand, heap management belongs to Standard Library rather than to > core language. In free-standing C implementation heap management can > be completely absent. You can certainly use C++ with little or no heap usage (I do that regularly), but you need to avoid many parts of the standard library. (Though it is possible to use custom allocators for some things.) > Last year I tried (not vary hard) to find > solution to that problem, but language design is not really my cup of > tee, so I was unable to invent anything satisfactory. > > At the end I came to conclusion, that for sort of jobs (in memory > constrained embedded environment) where I would not mind having > stackless co-routines, they are not necessarily the best > technical solution. > It's quite possible that normal co-routines, a.k.a. fibers, are better > solution. And fibers don't have to be part of core language or even of > Standard Library. However, fibers have one problem for which I would > prefer language support - sometimes, when running in slim fiber, I want > to call a "heavy" function, like sprintf or such, sort of function that > in worst case needs a lot of stack space. Today in such case I have to > provide a space for such function on stack of each and any fiber that > can potentially use it. If I have dozens of fibers, that would be quite > a lot wasted memory - instead of ~200 byte per fiber, or may be even > less, I'd have to allocate few KB. That's where enhancement in core > language code be handy - I want an ability to call a function not at > current stack, but on some sort of common stack, shared by all fibers > of the program. Or in case of multithreaded program, shared by all > fibers of particular thread. Of course, in theory that sort of > trampoline call/return could be implemented as a 3rd party library > function as well, but somehow I fill that it belongs to language, at > least as much as setjmp/lonjmp belongs to it, but preferably even in > more integrated manner, > > You are describing very familiar issues. I am increasingly convinced that to have an "ideal" language for constrained embedded systems, you need something significantly different from either C or C++ models. (And no, Rust is not any better.) But that would be well outside c.l.c., and I have not figured out the details of what would be needed. In the meantime, I just try to use microcontrollers with a bit more memory and speed overhead, and give my RTOS threads a bit more stack space. It feels like an inefficient solution, but it's a tradeoff of developer time to runtime resources - and the price of microcontrollers with a little more RAM drops faster than the cost of developers!
[toc] | [prev] | [next] | [standalone]
| From | Bonita Montero <Bonita.Montero@gmail.com> |
|---|---|
| Date | 2026-06-12 18:58 +0200 |
| Subject | Re: Co-routines (was Re: acquire + sleep + async) |
| Message-ID | <110hdsj$2bd29$1@raubtier-asyl.eternal-september.org> |
| In reply to | #399975 |
Am 12.06.2026 um 13:59 schrieb David Brown: > Of course you can jump back - longjmp() ... No, the stackframe of the function you've jumped out of is very likely to be overitten. > The source boilerplate code overhead for Protothreads is about a tenth > of that. This macro-hell sucks and isn't easy to be debugged. C sucks at all. > The overhead for other C coroutine libraries (or coroutines in languages with real support) is basically nothing. Resuming a coroutine in C++ also nearly costs nothing.
[toc] | [prev] | [next] | [standalone]
| From | Lawrence D’Oliveiro <ldo@nz.invalid> |
|---|---|
| Date | 2026-06-13 00:04 +0000 |
| Subject | Re: Continuations (was Re: Coroutines) |
| Message-ID | <110i6q4$2iqm8$5@dont-email.me> |
| In reply to | #399968 |
On Fri, 12 Jun 2026 13:18:00 +0200, Bonita Montero wrote: > With setjmp() and longjmp() you can jump out of a function, but not > back inside. Now you’re talking continuations! These are quite an interesting control abstraction, since they can be used to implement only those control constructs that could be considered well-structured. This covers quite a range (e.g. loops, exceptions, coroutines) but manages to rule out arbitrary gotos.
[toc] | [prev] | [next] | [standalone]
| From | Bart <bc@freeuk.com> |
|---|---|
| Date | 2026-06-12 14:51 +0100 |
| Subject | Re: Co-routines (was Re: acquire + sleep + async) |
| Message-ID | <110h2s3$27nuo$1@dont-email.me> |
| In reply to | #399964 |
On 12/06/2026 11:42, David Brown wrote:
> On 11/06/2026 18:50, Janis Papanagnou wrote:
>> On 2026-06-11 09:52, David Brown wrote:
>>> On 11/06/2026 09:21, Bonita Montero wrote:
>>>> C hasn't been improved much since 1973.
>>>
>>> What an astoundingly ignorant claim.
>>
>> I certainly wouldn't call her claim ignorant; I think it depends on
>> the abstraction level one has, but also on the expectations, about
>> what's possible, and what one knows from other languages or areas.
>>
>> In the stone-age era a club might have been considered a good tool.
>>
> In 1973, C was very new and primitive, and was quickly followed by a
> number of diverging and inconsistent versions. K&R C, the language from
> "The C Programming Language", was a huge improvement and standardisation
> compared to 1973 C. ANSI C / C89 / C90 was another massive step
> forward, as was C99.
It's still quite primitive.
Some bits have been more standardised. Some 'improvements' have been
done crudely and without touching the core language, for example by
bolting on stuff via extra headers.
Many changes have been low-key and dull, but then there have been others
that are over-ambitious for the language, such as VLAs and BitInt. Or
are just plain ugly, such as compound literals (see below).
Meanwhile most of the quirks and poor design aspects are still there.
It seems that there are two approaches commonly used to get around its
shortcomings:
* Use the macro processor, either via standard headers, or by everyone
rolling their own mini-solutions
* Putting a huge amount of effort into tools that can help detect or get
around problems, rather than actually fixing the language. But here,
those solutions are specific to the tool
This is not to say that C should have ended up looking like C++. That's
got its own problems, as well as inheriting many of C's.
> To suggest that C hasn't improved much since 1973 is either totally
> ignorant of the history of the language, or a deliberate lie. I choose
> to give Bonita the benefit of the doubt and assume ignorance.
BM doesn't like C because it doesn't have all the toys that C++ provides
and which they have become dependent on (and which strangely, always
seem to result in more complicated solutions than in C!).
-------
Regarding compound literals, why is one necessary when assigning to 'q'
here:
typedef struct {double x, y;} Point;
Point p = {10, 20};
Point q;
q = (Point){30, 40};
The initialisation of 'p' doesn't need it, so can't you just do this:
q = {30, 40};
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2026-06-12 16:04 +0200 |
| Subject | Re: Co-routines (was Re: acquire + sleep + async) |
| Message-ID | <110h3kp$24ih1$6@dont-email.me> |
| In reply to | #399985 |
On 12/06/2026 15:51, Bart wrote: > On 12/06/2026 11:42, David Brown wrote: >> On 11/06/2026 18:50, Janis Papanagnou wrote: >>> On 2026-06-11 09:52, David Brown wrote: >>>> On 11/06/2026 09:21, Bonita Montero wrote: > >>>>> C hasn't been improved much since 1973. >>>> >>>> What an astoundingly ignorant claim. >>> >>> I certainly wouldn't call her claim ignorant; I think it depends on >>> the abstraction level one has, but also on the expectations, about >>> what's possible, and what one knows from other languages or areas. >>> >>> In the stone-age era a club might have been considered a good tool. >>> >> In 1973, C was very new and primitive, and was quickly followed by a >> number of diverging and inconsistent versions. K&R C, the language >> from "The C Programming Language", was a huge improvement and >> standardisation compared to 1973 C. ANSI C / C89 / C90 was another >> massive step forward, as was C99. > > It's still quite primitive. Compared to many modern languages, it is small and simple. Its heritage goes back 50 years, but it has improved greatly since then. You don't like C - we know that. There's no need to put the broken record on repeat.
[toc] | [prev] | [next] | [standalone]
| From | Bart <bc@freeuk.com> |
|---|---|
| Date | 2026-06-12 16:16 +0100 |
| Subject | Re: Co-routines (was Re: acquire + sleep + async) |
| Message-ID | <110h7ru$299ii$1@dont-email.me> |
| In reply to | #399987 |
On 12/06/2026 15:04, David Brown wrote: > On 12/06/2026 15:51, Bart wrote: >> On 12/06/2026 11:42, David Brown wrote: >>> On 11/06/2026 18:50, Janis Papanagnou wrote: >>>> On 2026-06-11 09:52, David Brown wrote: >>>>> On 11/06/2026 09:21, Bonita Montero wrote: >> >>>>>> C hasn't been improved much since 1973. >>>>> >>>>> What an astoundingly ignorant claim. >>>> >>>> I certainly wouldn't call her claim ignorant; I think it depends on >>>> the abstraction level one has, but also on the expectations, about >>>> what's possible, and what one knows from other languages or areas. >>>> >>>> In the stone-age era a club might have been considered a good tool. >>>> >>> In 1973, C was very new and primitive, and was quickly followed by a >>> number of diverging and inconsistent versions. K&R C, the language >>> from "The C Programming Language", was a huge improvement and >>> standardisation compared to 1973 C. ANSI C / C89 / C90 was another >>> massive step forward, as was C99. >> >> It's still quite primitive. > > Compared to many modern languages, it is small and simple. Its heritage > goes back 50 years, but it has improved greatly since then. > > You don't like C - we know that. There's no need to put the broken > record on repeat. I was responding to the claims that C has improved significantly. You used 'huge improvement', 'massive step forward' and now 'improved greatly'. I don't see it, sorry. I'm also suggesting that what you are seeing are the /tools/ used to work with it. Try using a small C compiler and see if you get the same experience. Remember the language is the same!
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2026-06-12 17:31 +0200 |
| Subject | Re: Co-routines (was Re: acquire + sleep + async) |
| Message-ID | <110h8oa$29dhv$1@dont-email.me> |
| In reply to | #399990 |
On 12/06/2026 17:16, Bart wrote: > On 12/06/2026 15:04, David Brown wrote: >> On 12/06/2026 15:51, Bart wrote: >>> On 12/06/2026 11:42, David Brown wrote: >>>> On 11/06/2026 18:50, Janis Papanagnou wrote: >>>>> On 2026-06-11 09:52, David Brown wrote: >>>>>> On 11/06/2026 09:21, Bonita Montero wrote: >>> >>>>>>> C hasn't been improved much since 1973. >>>>>> >>>>>> What an astoundingly ignorant claim. >>>>> >>>>> I certainly wouldn't call her claim ignorant; I think it depends on >>>>> the abstraction level one has, but also on the expectations, about >>>>> what's possible, and what one knows from other languages or areas. >>>>> >>>>> In the stone-age era a club might have been considered a good tool. >>>>> >>>> In 1973, C was very new and primitive, and was quickly followed by a >>>> number of diverging and inconsistent versions. K&R C, the language >>>> from "The C Programming Language", was a huge improvement and >>>> standardisation compared to 1973 C. ANSI C / C89 / C90 was another >>>> massive step forward, as was C99. >>> >>> It's still quite primitive. >> >> Compared to many modern languages, it is small and simple. Its >> heritage goes back 50 years, but it has improved greatly since then. >> >> You don't like C - we know that. There's no need to put the broken >> record on repeat. > > > I was responding to the claims that C has improved significantly. > > You used 'huge improvement', 'massive step forward' and now 'improved > greatly'. > Yes. > I don't see it, sorry. I don't consider your opinions here to be of particular relevance - your hatred of everything related to C blinds you. You are so obsessed with what you perceive (and you have the right to your subjective opinions, likes and dislikes) as flaws in C that you are unable to see the improvements in the language over the years. I am not claiming C is in any sense "perfect" - merely that it has improved greatly since its conception. (I am aware that "improvements" are also subjective - if a programmer thinks implicit int, lack of function prototypes, lack of standardisation, etc., are all good things, then they might feel C has gone downhill since 1973.) > > I'm also suggesting that what you are seeing are the /tools/ used to > work with it. Try using a small C compiler and see if you get the same > experience. Remember the language is the same! > Your suggestion is incorrect. I /do/ think that tools for C have also improved massively, but that is in addition to improvements in the language. And I do not care how primitive small C compilers are, other than to note that if a small C compiler does not support newer C standards then it is of no relevance when discussing how the C language has been improved.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <Keith.S.Thompson+u@gmail.com> |
|---|---|
| Date | 2026-06-12 13:48 -0700 |
| Subject | Re: Co-routines (was Re: acquire + sleep + async) |
| Message-ID | <110hrar$2g518$2@kst.eternal-september.org> |
| In reply to | #399990 |
Bart <bc@freeuk.com> writes:
[...]
> I was responding to the claims that C has improved significantly.
>
> You used 'huge improvement', 'massive step forward' and now 'improved
> greatly'.
>
> I don't see it, sorry.
[...]
Yes, let's debate the meanings "huge improvement" and "massive step
forward", and whether the changes in C are huge, large, or minor.
Such debates are always interesting, productive, and illuminating.
--
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
void Void(void) { Void(); } /* The recursive call of the void */
[toc] | [prev] | [next] | [standalone]
| From | "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> |
|---|---|
| Date | 2026-06-13 14:13 -0700 |
| Subject | Re: Co-routines (was Re: acquire + sleep + async) |
| Message-ID | <110kh6j$375l8$1@dont-email.me> |
| In reply to | #400008 |
On 6/12/2026 1:48 PM, Keith Thompson wrote: > Bart <bc@freeuk.com> writes: > [...] >> I was responding to the claims that C has improved significantly. >> >> You used 'huge improvement', 'massive step forward' and now 'improved >> greatly'. >> >> I don't see it, sorry. > [...] > > Yes, let's debate the meanings "huge improvement" and "massive step > forward", and whether the changes in C are huge, large, or minor. > Such debates are always interesting, productive, and illuminating. > C11 is pretty huge for me. Added threads and memory barriers.
[toc] | [prev] | [next] | [standalone]
| From | fir <profesor.fir@gmail.com> |
|---|---|
| Date | 2026-06-12 16:25 +0200 |
| Subject | Re: Co-routines (was Re: acquire + sleep + async) |
| Message-ID | <110h4sl$28d0p$1@dont-email.me> |
| In reply to | #399985 |
Bart pisze:
> On 12/06/2026 11:42, David Brown wrote:
>> On 11/06/2026 18:50, Janis Papanagnou wrote:
>>> On 2026-06-11 09:52, David Brown wrote:
>>>> On 11/06/2026 09:21, Bonita Montero wrote:
>
>>>>> C hasn't been improved much since 1973.
>>>>
>>>> What an astoundingly ignorant claim.
>>>
>>> I certainly wouldn't call her claim ignorant; I think it depends on
>>> the abstraction level one has, but also on the expectations, about
>>> what's possible, and what one knows from other languages or areas.
>>>
>>> In the stone-age era a club might have been considered a good tool.
>>>
>> In 1973, C was very new and primitive, and was quickly followed by a
>> number of diverging and inconsistent versions. K&R C, the language
>> from "The C Programming Language", was a huge improvement and
>> standardisation compared to 1973 C. ANSI C / C89 / C90 was another
>> massive step forward, as was C99.
>
> It's still quite primitive.
>
> Some bits have been more standardised. Some 'improvements' have been
> done crudely and without touching the core language, for example by
> bolting on stuff via extra headers.
>
> Many changes have been low-key and dull, but then there have been others
> that are over-ambitious for the language, such as VLAs and BitInt. Or
> are just plain ugly, such as compound literals (see below).
>
> Meanwhile most of the quirks and poor design aspects are still there.
>
they not want to break c codes (and this is obviously right)
BUT it opens a question - it is possibility to
add c extensions as a form of compile flags
whose you could turn on or off...
it would then result in a situation when
some more new codes would use them and
the wuestion is if it is right way or no
i think that some really handy robably could be added
- like this -see-below i mentioned (makin symbols be visible not only up
in code but also down in code) OR that handy unsigned c ='shgshs' thing
which i would like to use
they could even add resizable rrays in fact
int tab[10];
foo()
{
tab.size*=1.5;
}
this is no problem in that (table is implemented
on heap, thise syntax just calls reallocks)
and that at least would be big change
ALSO they could add some things to standard c lib
(like this fopen for socket-like internet connections)
and possibly typeslike float3 and basic arithmetic
for them
[toc] | [prev] | [next] | [standalone]
| From | fir <profesor.fir@gmail.com> |
|---|---|
| Date | 2026-06-12 16:28 +0200 |
| Subject | Re: Co-routines (was Re: acquire + sleep + async) |
| Message-ID | <110h51i$28d0p$2@dont-email.me> |
| In reply to | #399988 |
fir pisze:
> Bart pisze:
>> On 12/06/2026 11:42, David Brown wrote:
>>> On 11/06/2026 18:50, Janis Papanagnou wrote:
>>>> On 2026-06-11 09:52, David Brown wrote:
>>>>> On 11/06/2026 09:21, Bonita Montero wrote:
>>
>>>>>> C hasn't been improved much since 1973.
>>>>>
>>>>> What an astoundingly ignorant claim.
>>>>
>>>> I certainly wouldn't call her claim ignorant; I think it depends on
>>>> the abstraction level one has, but also on the expectations, about
>>>> what's possible, and what one knows from other languages or areas.
>>>>
>>>> In the stone-age era a club might have been considered a good tool.
>>>>
>>> In 1973, C was very new and primitive, and was quickly followed by a
>>> number of diverging and inconsistent versions. K&R C, the language
>>> from "The C Programming Language", was a huge improvement and
>>> standardisation compared to 1973 C. ANSI C / C89 / C90 was another
>>> massive step forward, as was C99.
>>
>> It's still quite primitive.
>>
>> Some bits have been more standardised. Some 'improvements' have been
>> done crudely and without touching the core language, for example by
>> bolting on stuff via extra headers.
>>
>> Many changes have been low-key and dull, but then there have been
>> others that are over-ambitious for the language, such as VLAs and
>> BitInt. Or are just plain ugly, such as compound literals (see below).
>>
>> Meanwhile most of the quirks and poor design aspects are still there.
>>
>
> they not want to break c codes (and this is obviously right)
>
>
> BUT it opens a question - it is possibility to
> add c extensions as a form of compile flags
> whose you could turn on or off...
>
> it would then result in a situation when
> some more new codes would use them and
> the wuestion is if it is right way or no
>
> i think that some really handy robably could be added
> - like this -see-below i mentioned (makin symbols be visible not only up
> in code but also down in code) OR that handy unsigned c ='shgshs' thing
> which i would like to use
>
> they could even add resizable rrays in fact
>
> int tab[10];
>
> foo()
> {
> tab.size*=1.5;
> }
>
those resizable arrays (exact that) are imo absolute must in modern times c
> this is no problem in that (table is implemented
> on heap, thise syntax just calls reallocks)
>
> and that at least would be big change
>
> ALSO they could add some things to standard c lib
> (like this fopen for socket-like internet connections)
> and possibly typeslike float3 and basic arithmetic
> for them
>
[toc] | [prev] | [next] | [standalone]
| From | Janis Papanagnou <janis_papanagnou+ng@hotmail.com> |
|---|---|
| Date | 2026-06-12 19:13 +0200 |
| Subject | Re: Co-routines (was Re: acquire + sleep + async) |
| Message-ID | <110hene$2097v$3@dont-email.me> |
| In reply to | #399985 |
On 2026-06-12 15:51, Bart wrote:
> On 12/06/2026 11:42, David Brown wrote:
>> [ C-language ]
>
> It's still quite primitive.
>
> Some bits have been more standardised. Some 'improvements' have been
> done crudely and without touching the core language, for example by
> bolting on stuff via extra headers.
>
> Many changes have been low-key and dull, but then there have been others
> that are over-ambitious for the language, such as VLAs and BitInt. Or
> are just plain ugly, such as compound literals (see below).
>
> Meanwhile most of the quirks and poor design aspects are still there.
While I seem to share some aspects of your opinion I'm not as convinced
as you seem to be concerning sensible progress where you are hinting on
VLA and BitInt.
I think "C", as designed, cannot really evolve to something substantial
"better". That's why I _accept_ "C" as what it is, for its application
areas that undeniably are there!
> It seems that there are two approaches commonly used to get around its
> shortcomings:
>
> * Use the macro processor, either via standard headers, or by everyone
> rolling their own mini-solutions
That, Cpp, never appeared to me as anything solving any inherent flaw.
>
> * Putting a huge amount of effort into tools that can help detect or get
> around problems, rather than actually fixing the language. But here,
> those solutions are specific to the tool
I think you cannot really "fix" the language. It is what it is. And it
won't substantially change, I'd guess, given its evolution during the
past decades.
*** warning *** below this point there's mostly only C++ stuff ***
>
> This is not to say that C should have ended up looking like C++. That's
> got its own problems, as well as inheriting many of C's.
>
>> [...]
>
> BM doesn't like C because it doesn't have all the toys that C++ provides
What "toys"?
> and which they have become dependent on (and which strangely,
You mean, like STL, as *standard* part of the language? - Or what?
> always seem to result in more complicated solutions than in C!).
I suggest to use simple means for simple things (in "C" and in C++).
For complex things you have much better structuring means than in "C",
so for non-trivial things you gain clarity and simplicity with C++.
(The latter is what I understand was also Bonita trying to convey.)
>
> -------
>
> Regarding compound literals, why is one necessary when assigning to 'q'
> here:
>
> typedef struct {double x, y;} Point;
>
> Point p = {10, 20};
> Point q;
> q = (Point){30, 40};
>
> The initialisation of 'p' doesn't need it, so can't you just do this:
>
> q = {30, 40};
>
I'm not sure what that convoluted C-syntax is supposed to explain.
Your brain seems so used to old "C" patterns that you missed the
possibilities that other higher-level languages like C++ provide.
The C++ syntax is just: struct Point { ... };
Or, if you want "access control": class Point { ... };
Point appears to me to be a "fundamental" type, and so I'd certainly
have a class defined, so that I can do sensible operations on Point
objects.
My C++ days are long history, but I certainly had Point declarations
in code that could be used as in
Point p (10, 30);
Point q;
q = Point (30, 40);
Point r;
r = { 20, 70 }; // if you feel more comfortable with that syntax
Line s (p, q); // just an extension to show how nicely it extends
and so on.
The point is that (for non-toy code!) it pays to design classes and
then make use of clean and consistent expressions as I depicted above.
For above to work you only need to define the usual constructors, i.e.
instead of
struct Point { int x, y; };
you declare it with two sensible any typical constructors for Point
struct Point { int x, y;
Point (int _x, int _y) : x(_x), y(_y) {};
Point (void) : x(0), y(0) {};
};
and you can then make use of the clear syntax I showed above.
Those Constructors may look strange to the uninitiated C-user; you
certainly have to _learn_ the language - as you should learn "C"!
Janis
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <Keith.S.Thompson+u@gmail.com> |
|---|---|
| Date | 2026-06-12 13:45 -0700 |
| Subject | Re: Co-routines (was Re: acquire + sleep + async) |
| Message-ID | <110hr5s$2g518$1@kst.eternal-september.org> |
| In reply to | #399985 |
Bart <bc@freeuk.com> writes:
[...]
> It's still quite primitive.
>
> Some bits have been more standardised. Some 'improvements' have been
> done crudely and without touching the core language, for example by
> bolting on stuff via extra headers.
What you call "crude", I call taking advantage of existing language
features to add new functionality without having to change the
core language.
The uint32_t et al types could have been added as keywords
(even, as you would no doubt have preferred, with different
names), but it wasn't necessary to do so. Defining them in
a header made it possible to duplicate the functionality for
use with pre-C99 compilers; see for example Doug Gwyn's q8,
<https://www.lysator.liu.se/c/q8/index.html>. (And if you think the
fixed-width types are in some sense more fundamental than short,
int, long et al, and the former should be keywords and the latter
should be typedefs, that's a valid opinion, but C isn't going to
make that particular change.)
When C added complex number support, it was done as a core language
feature because the language didn't provide the facilities to define
it in a header. C++ did it in a header, because it was possible
to do so.
[...]
> Regarding compound literals, why is one necessary when assigning to
> 'q' here:
>
> typedef struct {double x, y;} Point;
>
> Point p = {10, 20};
> Point q;
> q = (Point){30, 40};
>
> The initialisation of 'p' doesn't need it, so can't you just do this:
>
> q = {30, 40};
Because an initializer is evaluated in a context that depends on the
type of the object being initialized, but an expression, even if it's
the RHS of an assignment, is not.
In almost all cases, the type and semantics of an expression (even if
it's a subexpression) are fully determined by the expression itself,
not by the context in which it appears. 42 is of type int, even when
it's assigned to a floating-point object; the assignment imposes a
conversion.
In `Point p = {10, 20};`, the initializer is evaluated in a context
where the compiler knows that the result type is Point.
In `p = {10, 20};`, if it weren't a syntax error, the compiler
would not (be required to) know that {10, 20} is being assigned
to an object of type Point. It could be some other struct type,
or an array.
There are languages that work differently. In Ada, for example, the
equivalent `P := (10, 20);` is valid, because the RHS is evaluated
in a context that takes the type of the LHS into account. (10, 20)
is a valid expression in Ada, and its type depends on its context.
(Ada doesn't have expression statements, so there always a context.)
When compound literals were added to the language, there were several
options:
1. Rework expression evaluation so that the type of an expression
depends on its context. Specify that a braced-initializer is a
kind of expression. Write several pages of standardese specifying
exactly when and how this happens. Then `p = {10, 20};` is
valid, and `{10, 20}` is of type Point. Presumably an expression
statement `{10, 20};` would be a constraint violation, because
there's no context to determine its type. Decide whether
`ptr = &{10, 20};` determines the type of `{10, 20}` or not.
Argue for years about whether this breaks existing code, and
how much of a problem that is.
2. A special-case version of the above, where a braced initializer
is an expression, and its type is determined by its context.
Write several pages of standardese specifying exactly how
the context determines the type and the cases where the type
can't be determined and therefore a constraint is violated.
Contexts include the RHS of an assignment, a function argument,
and so on. Specify that a braced initializer that is, or
is part of, an initializer is *not* an expression (otherwise
`int arr[2] = {10, 20};` would become invalid) -- but maybe
a parenthesized braced-initializer expression can be used
in an initializer? Argue for years about that.
3. Make the syntax of a compound literal just a little more
explicit, consisting of a parenthesized type name followed a
braced initializer, so the type must be specified rather than
inferred.
--
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
void Void(void) { Void(); } /* The recursive call of the void */
[toc] | [prev] | [next] | [standalone]
| From | Bart <bc@freeuk.com> |
|---|---|
| Date | 2026-06-13 01:03 +0100 |
| Subject | Re: Co-routines (was Re: acquire + sleep + async) |
| Message-ID | <110i6oe$2j5rp$1@dont-email.me> |
| In reply to | #400007 |
On 12/06/2026 21:45, Keith Thompson wrote:
> Bart <bc@freeuk.com> writes:
> [...]
>> It's still quite primitive.
>>
>> Some bits have been more standardised. Some 'improvements' have been
>> done crudely and without touching the core language, for example by
>> bolting on stuff via extra headers.
>
> What you call "crude", I call taking advantage of existing language
> features to add new functionality without having to change the
> core language.
>
> The uint32_t et al types could have been added as keywords
> (even, as you would no doubt have preferred, with different
> names), but it wasn't necessary to do so.
It's a poor approach:
* Those types don't exist unless stdint.h is present. That means anyone
could define their own non-compatible versions
* Even if stdint.h is used, people could still shadow the names for
their own purposes
* Whether a particular stdint type is exactly compatible with a built-in
type can vary between implementations, causing problems with _Generic
for example
* There are problems with literals for such types, and printf support,
necessitating an auxiliary intypes.h header with lots of ugly macros.
So, yeah it's crude. I also don't see the advantage of not changing the
core language. Such changes were needed in C99 anyway in order to
support VLA, variable modified types, compound literals, designated
initialiser, probably some other stuff.
Building in those types was arguably simpler than most of those. And
advantage could have been taken to introduce a built-in way of getting
integer limits (say _Minvalue(T) and _Maxvalue(T)), or even _Minvalue(X)
etc), instead of dedicated macros for every conceivable type.
And this is just one feature.
> Defining them in
> a header made it possible to duplicate the functionality for
> use with pre-C99 compilers; see for example Doug Gwyn's q8,
> <https://www.lysator.liu.se/c/q8/index.html>.
Everyone made their arrangements anyway. Many still do.
(And if you think the
>> Regarding compound literals, why is one necessary when assigning to
>> 'q' here:
>>
>> typedef struct {double x, y;} Point;
>>
>> Point p = {10, 20};
>> Point q;
>> q = (Point){30, 40};
>>
>> The initialisation of 'p' doesn't need it, so can't you just do this:
>>
>> q = {30, 40};
>
> Because an initializer is evaluated in a context that depends on the
> type of the object being initialized, but an expression, even if it's
> the RHS of an assignment, is not.
> In almost all cases, the type and semantics of an expression (even if
> it's a subexpression) are fully determined by the expression itself,
> not by the context in which it appears. 42 is of type int, even when
> it's assigned to a floating-point object; the assignment imposes a
> conversion.
>
> In `Point p = {10, 20};`, the initializer is evaluated in a context
> where the compiler knows that the result type is Point.
>
> In `p = {10, 20};`, if it weren't a syntax error,
It wouldn't be if allowed.
> the compiler
> would not (be required to) know that {10, 20} is being assigned
> to an object of type Point. It could be some other struct type,
> or an array.
And?
I use the term 'closed' for an expression that occurs in a known
context: something will be done with it and the type is known (pass to a
function, assign to a variable, cast it to T etc).
And 'open' for an expression that is not used for anything and so there
is no final type to conform too. Here:
q = {30, 40};
The RHS is closed. By itself, it's some generic constructor, but it is
being assigned to 'q', so it knows it is supposed to be a Point type.
> There are languages that work differently. In Ada, for example, the
> equivalent `P := (10, 20);` is valid, because the RHS is evaluated
> in a context that takes the type of the LHS into account. (10, 20)
> is a valid expression in Ada, and its type depends on its context.
> (Ada doesn't have expression statements, so there always a context.)
>
> When compound literals were added to the language, there were several
> options:
>
> 1. Rework expression evaluation so that the type of an expression
> depends on its context.
? Specify that a braced-initializer is a
> kind of expression. Write several pages of standardese specifying
> exactly when and how this happens. Then `p = {10, 20};` is
> valid, and `{10, 20}` is of type Point. Presumably an expression
> statement `{10, 20};` would be a constraint violation, because
> there's no context to determine its type. Decide whether
> `ptr = &{10, 20};` determines the type of `{10, 20}` or not.
> Argue for years about whether this breaks existing code, and
> how much of a problem that is.
>
> 2. A special-case version of the above, where a braced initializer
> is an expression, and its type is determined by its context.
> Write several pages of standardese specifying exactly how
> the context determines the type and the cases where the type
> can't be determined and therefore a constraint is violated.
This need not be as hard as you make out.
{...} used for initialising is already different.
There is a possible ambiguity where {...} is used for a compound
statement, but it could also be a data constructor. But I think that can
be solved because {...} used for data happens in value-returning contexts.
> Contexts include the RHS of an assignment, a function argument,
> and so on. Specify that a braced initializer that is, or
> is part of, an initializer is *not* an expression (otherwise
> `int arr[2] = {10, 20};` would become invalid) -- but maybe
> a parenthesized braced-initializer expression can be used
> in an initializer?
I use parentheses (see below); it seems to work. One small issue is when
there is only one data element, then I need to write (10,) instead of
(10), which looks like a scalar expression.
That could probably be fixed, but it wouldn't happen with {10}.
------------------------------
record point = (real x, y)
point p := (10, 20)
point q
q := (30, 40)
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <Keith.S.Thompson+u@gmail.com> |
|---|---|
| Date | 2026-06-12 17:50 -0700 |
| Subject | Re: Co-routines (was Re: acquire + sleep + async) |
| Message-ID | <110i9g0$2jcdv$1@kst.eternal-september.org> |
| In reply to | #400014 |
Bart <bc@freeuk.com> writes:
> On 12/06/2026 21:45, Keith Thompson wrote:
>> Bart <bc@freeuk.com> writes:
>> [...]
>>> It's still quite primitive.
>>>
>>> Some bits have been more standardised. Some 'improvements' have been
>>> done crudely and without touching the core language, for example by
>>> bolting on stuff via extra headers.
>> What you call "crude", I call taking advantage of existing language
>> features to add new functionality without having to change the
>> core language.
>> The uint32_t et al types could have been added as keywords
>> (even, as you would no doubt have preferred, with different
>> names), but it wasn't necessary to do so.
>
> It's a poor approach:
>
> * Those types don't exist unless stdint.h is present. That means anyone
> could define their own non-compatible versions
"Doctor, it hurts when I do this."
> * Even if stdint.h is used, people could still shadow the names for
> their own purposes
"Doctor, it hurts when I do this."
Even if int32_t where a keyword (only on implementations with 32-bit
integers?), you could redefine it as a macro. So don't do that.
Yes, there are some inconvenient issues. We've been dealing with them
successfully for decades.
[SNIP]
>>> Regarding compound literals, why is one necessary when assigning to
>>> 'q' here:
>>>
>>> typedef struct {double x, y;} Point;
>>>
>>> Point p = {10, 20};
>>> Point q;
>>> q = (Point){30, 40};
>>>
>>> The initialisation of 'p' doesn't need it, so can't you just do this:
>>>
>>> q = {30, 40};
>> Because an initializer is evaluated in a context that depends on the
>> type of the object being initialized, but an expression, even if it's
>> the RHS of an assignment, is not.
>
>> In almost all cases, the type and semantics of an expression (even if
>> it's a subexpression) are fully determined by the expression itself,
>> not by the context in which it appears. 42 is of type int, even when
>> it's assigned to a floating-point object; the assignment imposes a
>> conversion.
>> In `Point p = {10, 20};`, the initializer is evaluated in a context
>> where the compiler knows that the result type is Point.
>> In `p = {10, 20};`, if it weren't a syntax error,
>
> It wouldn't be if allowed.
No kidding.
>> the compiler
>> would not (be required to) know that {10, 20} is being assigned
>> to an object of type Point. It could be some other struct type,
>> or an array.
>
> And?
And ... you should read what I wrote if you want to understand it?
> I use the term 'closed' for an expression that occurs in a known
> context: something will be done with it and the type is known (pass to
> a function, assign to a variable, cast it to T etc).
>
> And 'open' for an expression that is not used for anything and so
> there is no final type to conform too. Here:
>
> q = {30, 40};
>
> The RHS is closed. By itself, it's some generic constructor, but it is
> being assigned to 'q', so it knows it is supposed to be a Point type.
That's nice.
As I said, in some languages the type and semantics of an expression
depend on its context. C is not such a language. You advocate a
radical change to the way C compilers handle expressions because
you find the syntax of compound literals (which works perfectly
well) icky.
No.
>> There are languages that work differently. In Ada, for example, the
>> equivalent `P := (10, 20);` is valid, because the RHS is evaluated
>> in a context that takes the type of the LHS into account. (10, 20)
>> is a valid expression in Ada, and its type depends on its context.
>> (Ada doesn't have expression statements, so there always a context.)
>> When compound literals were added to the language, there were
>> several
>> options:
>> 1. Rework expression evaluation so that the type of an expression
>> depends on its context.
> ? Specify that a braced-initializer is a
>> kind of expression. Write several pages of standardese specifying
>> exactly when and how this happens. Then `p = {10, 20};` is
>> valid, and `{10, 20}` is of type Point. Presumably an expression
>> statement `{10, 20};` would be a constraint violation, because
>> there's no context to determine its type. Decide whether
>> `ptr = &{10, 20};` determines the type of `{10, 20}` or not.
>> Argue for years about whether this breaks existing code, and
>> how much of a problem that is.
>> 2. A special-case version of the above, where a braced initializer
>> is an expression, and its type is determined by its context.
>> Write several pages of standardese specifying exactly how
>> the context determines the type and the cases where the type
>> can't be determined and therefore a constraint is violated.
>
> This need not be as hard as you make out.
It wasn't that hard, because the committee went with option 3,
the one you snipped. (Which is not to suggest that they actually
considered option 1 or 2.)
> {...} used for initialising is already different.
Yes, of course it's different. {...} is not an expression.
> There is a possible ambiguity where {...} is used for a compound
> statement, but it could also be a data constructor. But I think that
> can be solved because {...} used for data happens in value-returning
> contexts.
Fortunately, we didn't have to solve that problem, because the
actual syntax for compound literals is unambiguous.
[...]
> record point = (real x, y)
>
> point p := (10, 20)
> point q
> q := (30, 40)
Not C. Don't care.
--
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
void Void(void) { Void(); } /* The recursive call of the void */
[toc] | [prev] | [next] | [standalone]
| From | Bart <bc@freeuk.com> |
|---|---|
| Date | 2026-06-13 11:03 +0100 |
| Subject | Re: Co-routines (was Re: acquire + sleep + async) |
| Message-ID | <110j9sl$2rhme$1@dont-email.me> |
| In reply to | #400017 |
On 13/06/2026 01:50, Keith Thompson wrote:
> Bart <bc@freeuk.com> writes:
>> On 12/06/2026 21:45, Keith Thompson wrote:
>>> Bart <bc@freeuk.com> writes:
>>> [...]
>>>> It's still quite primitive.
>>>>
>>>> Some bits have been more standardised. Some 'improvements' have been
>>>> done crudely and without touching the core language, for example by
>>>> bolting on stuff via extra headers.
>>> What you call "crude", I call taking advantage of existing language
>>> features to add new functionality without having to change the
>>> core language.
>>> The uint32_t et al types could have been added as keywords
>>> (even, as you would no doubt have preferred, with different
>>> names), but it wasn't necessary to do so.
>>
>> It's a poor approach:
>>
>> * Those types don't exist unless stdint.h is present. That means anyone
>> could define their own non-compatible versions
>
> "Doctor, it hurts when I do this."
>> * Even if stdint.h is used, people could still shadow the names for
>> their own purposes
>
> "Doctor, it hurts when I do this."
Seriously? You have a language where you can literally do this:
#include <stdint.h>
int32_t int32_t;
int32_t = 0;
and that is just fine; just "don't do it"! In that case, we might as
well allow:
int int;
Can you understand how crazy the above looks from outside?
> As I said, in some languages the type and semantics of an expression
> depend on its context. C is not such a language. You advocate a
> radical change to the way C compilers handle expressions because
> you find the syntax of compound literals (which works perfectly
> well) icky.
But it woud be nicer if they didn't need that cast, yes? So having to
write it is less desirable.
>> {...} used for initialising is already different.
>
> Yes, of course it's different. {...} is not an expression.
Maybe that was the problem.
>> There is a possible ambiguity where {...} is used for a compound
>> statement, but it could also be a data constructor. But I think that
>> can be solved because {...} used for data happens in value-returning
>> contexts.
>
> Fortunately, we didn't have to solve that problem, because the
> actual syntax for compound literals is unambiguous.
Sure:
int a;
a = (int){123.45};
a = (int)(123.45);
Nothing to see here.
> [...]
>
>> record point = (real x, y)
>>
>> point p := (10, 20)
>> point q
>> q := (30, 40)
>
> Not C. Don't care.
And yet you said this:
"In Ada, for example, the equivalent `P := (10, 20);` is valid, because
the RHS is evaluated...".
My language is much closer to C, and it doesn't have much problem with
it. I was merely asking why you have to write:
DrawLine((Point){x1, y1}, (Point){x2, y2});
rather than:
DrawLine({x1, y1}, {x2, y2});
I know the {} are necessary in part because of the 'comma' operator,
which stops you being able to use (x1, y1) here, or A[i, j] for 2D indexing.
[toc] | [prev] | [next] | [standalone]
Page 4 of 5 — ← Prev page 1 2 3 [4] 5 Next page →
Back to top | Article view | comp.lang.c
csiph-web