im not experienced with multithreading programing (though i learned a
bit of it 20 years ago i decided it is not nice for me enough to do it)
i only tend to do things that seem reasonable to me and i have some doubts
hovever in my small view on things i may say that
I.
˙sleep() function
(who puts cpu core on sleep given miliseconds (or microseconds)
(by put on sleep i also thing it just chnges the context of execution
to anuther thread for given time eventually) I FIND REASONABLE
(i see no problem with that)
II.
async call of function (it is a call to some function that spawns a
thread, so main thread continues but the second spawned on that function executes also until it find some of async end when its job is done
I ALSO FIND reasoneble (no problem with that)
III.
there is a third thing...i name it acquire ..it is some kind os assembly instruction or pair of assembly instustions with some guarantees
i mean acquire(x) should work if(x==0) x=TID (thread id or something
like that) so its like conditional move˙˙ mov eax, tid; movz x, eax;
(where movz would mean here mov if x is 0 if not set a cpu flag)
and this should be proof of core crashes on this acces i mean only one
can acquire (im not sure if present cpu have it - that probably should
have - becouse it makes such operation very cheap then)
NOTE im meybe even less sura about this acquire becouse theoretically probably such acquireless (and maybe even mostly sleepless) programming
is possible but im not sure if it wouldnt be handy too
THOSE 3 "PRIMITIVES" imo are quite A SET to make multithreaded
programming "by hand".i also think it should be most lightweight,
i mean async call should be very light probbly (and probbaly it is its a metter of line of assembly or two i hope)...same with sleep (as in fact sleep and async call are close things
so i would hope that should be just maybe a set of few assebly opcodes
(if i not mislooked and something heavvier is needed)
conclusion is what i already said it seem that those 3 thing
(primitives) allows to do a lot of multithreading without bloated
libraries i hope
eventually correct me if im wrong
(also not to say they are best way of doing multithreading but if they
are lightweight it is at least minimally reasonable in some way it seems)
im not experienced with multithreading programing ...
That?s why it is best reserved for CPU-intensive tasks that can
benefit from running a bunch of cores at once.
For cases where the bottleneck is in the I/O or the network connection
(which is a lot of them), threading is typically unnecessary. Instead,
the popular approach nowadays is to use coroutines. <https://developer.mozilla.org/en-US/docs/Learn_web_development/Extensions/Async_JS/Introducing>
<https://docs.python.org/3/library/asyncio.html>
There are no coroutines in C.
On Thu, 11 Jun 2026 07:20:18 +0200, Bonita Montero wrote:
There are no coroutines in C.
Yes, C is getting left behind in this regard ...
C hasn't been improved much since 1973. You still stick with the
same lowlevel view.
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.
Yes, C is getting left behind in this regard ...
C hasn't been improved much since 1973.
You still stick with the same lowlevel view.
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.˙...
C hasn't been improved much since 1973.
What an astoundingly ignorant claim.
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).
Yes, C is getting left behind in this regard ...
C hasn't been improved much since 1973.
What an astoundingly ignorant claim.
You still stick with the same lowlevel view.
Am 11.06.2026 um 09:52 schrieb David Brown:
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.˙...
Real coroutines aren't possible with C since with native coroutines you
need functions that can be suspended and resumed.
C hasn't been improved much since 1973.
What an astoundingly ignorant claim.
Compared to C++ that's true.
Bonita Montero pisze:
Real coroutines aren't possible with C since with native coroutines you
need functions that can be suspended and resumed.
c lasks some low lewel core management imo -it is more visible in
multicore times..but even in old times there was something like
interrupts - who allowed theoretically but probably also practically
freeze a branch and resume it - so somemechanics of multthreading
was even on 1core machines - i remember it was in 8-bit c64 really
as to coroutines i interested in them about 10 yers ago but forget
what it is
Am 11.06.2026 um 09:52 schrieb David Brown:
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.˙...
Real coroutines aren't possible with C since with native coroutines you
need functions that can be suspended and resumed.
C hasn't been improved much since 1973.
What an astoundingly ignorant claim.
Compared to C++ that's true.
There are stackless coroutine libraries for C that work entirely from
the pre-processor, with similar limitations to the C++ coroutines (like
not being able to yield from normal functions called from the
coroutine).˙ There are also stackful coroutine libraries, which are more flexible but have higher overhead.
C coroutine solutions require more manual coding than C++ for tracking
local variables that must be preserved between calls/yields, but on the other hand they don't require the dog's breakfast of boilerplate classes
and code that C++ coroutines need.
It is still an astoundingly ignorant claim.˙ If you had said C had not changed much since 1999, it would be reasonable - though C23 has quite a number of new features.˙ And even then it would only be in reference to
the C standards - the C ecosystem has changed enormously.
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).
Yes, C is getting left behind in this regard ...
C hasn't been improved much since 1973.
What an astoundingly ignorant claim.
You still stick with the same lowlevel view.
On Wed, 10 Jun 2026 13:53:59 +0200, fir wrote:
im not experienced with multithreading programing ...
It does tend to be error-prone.
That?s why it is best reserved for CPU-intensive tasks that can
benefit from running a bunch of cores at once.
For cases where the bottleneck is in the I/O or the network connection
(which is a lot of them), threading is typically unnecessary. Instead,
the popular approach nowadays is to use coroutines.
<https://developer.mozilla.org/en-US/docs/Learn_web_development/Extensions/Async_JS/Introducing>
<https://docs.python.org/3/library/asyncio.html>
On Thu, 11 Jun 2026 09:21:13 +0200, Bonita Montero wrote:
C hasn't been improved much since 1973. You still stick with the
same lowlevel view.
Actually, just as you can use threading APIs with C, you can use
stackful coroutine libraries as well.
Stackless ones are another matter.
Bonita Montero pisze:
Am 11.06.2026 um 09:52 schrieb David Brown:
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.˙...
Real coroutines aren't possible with C since with native coroutines you
need functions that can be suspended and resumed.
c lasks some low lewel core management imo -it is more visible in
multicore times..but even in old times there was something like
interrupts - who allowed theoretically but probably also practically
freeze a branch and resume it - so somemechanics of multthreading
was even on 1core machines - i remember it was in 8-bit c64 really
C hasn't been improved much since 1973.
What an astoundingly ignorant claim.
Compared to C++ that's true.
On 6/10/2026 9:40 PM, Lawrence D?Oliveiro wrote:
For cases where the bottleneck is in the I/O or the network
connection (which is a lot of them), threading is typically
unnecessary. Instead, the popular approach nowadays is to use
coroutines.
Not sure why you say that.
It does tend to be error-prone.
That?s why it is best reserved for CPU-intensive tasks that can
benefit from running a bunch of cores at once.
Coroutines are the most elegant way to handle finite state machines.
They need explicit language support and can't be handled exclsuively
with libraries.
Real coroutines aren't possible with C since with native coroutines
you need functions that can be suspended and resumed.
Coroutines have nothing to do with multithreaded programming, but
they can be used to have sth. more lightweight than threading.
... per fibers on threads is a, well, kind of a different story.
On Thu, 11 Jun 2026 16:01:47 -0700, Chris M. Thomasson wrote:
... per fibers on threads is a, well, kind of a different story.
Are these ?fibre? things just some kind of runtime abstraction built
on top of OS threads?
On Thu, 11 Jun 2026 14:18:09 -0700, Chris M. Thomasson wrote:
On 6/10/2026 9:40 PM, Lawrence D?Oliveiro wrote:
For cases where the bottleneck is in the I/O or the network
connection (which is a lot of them), threading is typically
unnecessary. Instead, the popular approach nowadays is to use
coroutines.
Not sure why you say that.
It does tend to be error-prone.
That?s why it is best reserved for CPU-intensive tasks that can
benefit from running a bunch of cores at once.
C coroutine solutions require more manual coding than C++ for tracking[...]
local variables that must be preserved between calls/yields, but on the other hand they don't require the dog's breakfast of boilerplate classes
and code that C++ coroutines need.
I don?t know what?s ?heavyweight? about threading, beyond the stack allocations. ...
On Thu, 11 Jun 2026 10:28:55 +0200, Bonita Montero wrote:
Real coroutines aren't possible with C since with native coroutines
you need functions that can be suspended and resumed.
Just think of them as non-preemptive threads.
Am 12.06.2026 um 03:32 schrieb Lawrence D?Oliveiro:
I don?t know what?s ?heavyweight? about threading, beyond the stack
allocations. ...
Yes, the allocation of the stack is very expensive. And the
context-switch between threads is a magnitudes more expensive
than switching between two coroutine conexts.
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).
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.
Being a very subjective matter I suggest to abandon that subtopic.
The fibers float along the threads... ;^)
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).
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.
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:
In 1973, C was very new and primitive, and was quickly followed by aC 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.
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.
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:
In 1973, C was very new and primitive, and was quickly followed by aC 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.
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.
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:
In 1973, C was very new and primitive, and was quickly followed by aC 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.
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.
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:
In 1973, C was very new and primitive, and was quickly followed by aC 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.
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
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:
In 1973, C was very new and primitive, and was quickly followed by aC 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.
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.
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:
In 1973, C was very new and primitive, and was quickly followed by aC 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.
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!
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.
[ coroutines; C++, C, Go, Python ]
[ about substantial progress in C-language evolution ]
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!
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,
Of course you can jump back - longjmp() ...
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.
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.
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.
[...]
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};
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.
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 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.
Am 12.06.2026 um 03:32 schrieb Lawrence D?Oliveiro:
I don?t know what?s ?heavyweight? about threading, beyond the stack
allocations. ...
Yes, the allocation of the stack is very expensive. And the
context-switch between threads is a magnitudes more expensive than
switching between two coroutine conexts.
On 6/11/2026 6:33 PM, Lawrence D?Oliveiro wrote: > > Are these
?fibre? things just some kind of runtime abstraction > built on top
of OS threads? Basically. You need to make your own scheduler for the
fiber on the threads.
FWIW, check this shit out. Coroutines can be emulated even in BASIC.
This is a recursive stack here. Its all manual... :^)
[code omitted]
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>.
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? Specify that a braced-initializer is a
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.
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?
With setjmp() and longjmp() you can jump out of a function, but not
back inside.
On 12/06/2026 21:45, Keith Thompson wrote:
Bart <bc@freeuk.com> writes:
[...]
It's still quite primitive.What you call "crude", I call taking advantage of existing language
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.
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
Regarding compound literals, why is one necessary when assigning toBecause an initializer is evaluated in a context that depends on the
'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};
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? Specify that a braced-initializer is a
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.
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.
record point = (real x, y)
point p := (10, 20)
point q
q := (30, 40)
On Fri, 12 Jun 2026 06:16:42 +0200, Bonita Montero wrote:
Yes, the allocation of the stack is very expensive. And the
context-switch between threads is a magnitudes more expensive than
switching between two coroutine conexts.
Why should that be? What extra overhead is there in context-switching
between preemptive threads, versus non-preemptive ones?
Bart <bc@freeuk.com> writes:
On 12/06/2026 21:45, Keith Thompson wrote:
Bart <bc@freeuk.com> writes:
[...]
It's still quite primitive.What you call "crude", I call taking advantage of existing language
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.
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."
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.
{...} 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.
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?
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});
On 6/13/26 12:03, Bart wrote:
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?
˙˙ In our technical jargon, we have the perfect acronym to
˙˙ describe this kind of programming: GIGO. Look at wikipedia
˙˙ for an astounding description of that syndrom.
˙˙ https://en.wikipedia.org/wiki/Garbage_in,_garbage_out
On 2026-06-13 12:14, tTh wrote:
On 6/13/26 12:03, Bart wrote:
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?
Yes. (And I suppose everyone here understands that!)
Languages have various possibilities to define their lexical rules,
their syntax, and their semantics.
It's certainly quite common to have _reserved words_ that may only
be used in certain syntactical contexts. But there's also languages
that allow context-depending placement of names that happen to be
also tokens of the language.
Consider, for example, in shell:˙˙ for for in in do ; do : ; done
Such pieces of code are a result of a programmer's sick brain andSuch pieces of code are 100% *enabled* by the language so, yes, you can
not the problem of a language.
Keith already noted: "Doctor, it hurts when I do this."
And tTh said:
˙˙˙ In our technical jargon, we have the perfect acronym to
˙˙˙ describe this kind of programming: GIGO. Look at wikipedia
˙˙˙ for an astounding description of that syndrom.
˙˙˙ https://en.wikipedia.org/wiki/Garbage_in,_garbage_out
Bart, do you understand these hints? When will you recognize that
"the problem" is your personal thing? (That's all just rhetorical;
we know the answer: "Never!")
Am 13.06.2026 um 01:52 schrieb Lawrence D?Oliveiro:
On Fri, 12 Jun 2026 06:16:42 +0200, Bonita Montero wrote:
Yes, the allocation of the stack is very expensive. And the
context-switch between threads is a magnitudes more expensive than
switching between two coroutine conexts.
Why should that be? What extra overhead is there in context-switching
between preemptive threads, versus non-preemptive ones?
Because with threading the context-switch happens inside the kernel.
On Thu, 11 Jun 2026 21:11:13 -0700, Chris M. Thomasson wrote:
FWIW, check this shit out. Coroutines can be emulated even in BASIC.
This is a recursive stack here. Its all manual... :^)
[code omitted]
I see a lot of ?GOSUB 8000? within the subroutine starting at line
8000, so that?s a lot of recursion, not coroutines. Plus you?ve got
the explicit RS array stack for assembling the components of the
curve. Normally you would either have either recursion or an explicit
stack, since each one subsumes the functions of the other, so there
shouldn?t be a need for both.
In other words, I think you?ve got the worst of both worlds? Recursion
that isn?t enough to solve the problem purely recursively, plus an
explicit stack that isn?t enough to keep track of the entire stack
state?
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.
On 13/06/2026 13:35, Janis Papanagnou wrote:
On 2026-06-13 12:14, tTh wrote:
On 6/13/26 12:03, Bart wrote:Yes. (And I suppose everyone here understands that!)
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?
Thank you for at least acknowledging that.
In the case of 'int32_t' this is supposedly a core C type but it is
quite unknown to the language until you include a particular header.
But my example highlighted the fact that you can do this:
Point Point;
provided the first Point is a user-defined type defined in an outer
scope. Further:
Point typedef Point; // new scope starts at that 'typedef'
{Point Point;}
The attitude here seems to be, if you can write nonsense in any
language anyway, then why bother making it harder to do so? Let's have
fewer rules and make it easier!
Bart <bc@freeuk.com> writes:
On 13/06/2026 13:35, Janis Papanagnou wrote:
On 2026-06-13 12:14, tTh wrote:
On 6/13/26 12:03, Bart wrote:Yes. (And I suppose everyone here understands that!)
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?
Thank you for at least acknowledging that.
You seem think that acknowledgement is important. Upthread, you
asked a question. I spent substantial time and effort answering
it. You have not acknowledged that. I don't think you've ever
acnowledged it when I've answered one of your questions. Why is
that?
(I don't expect acknowledgement from you. I enjoyed writing the
explanation, and I hope that others might benefit from it, or at
least find it interesting.)
[...]
In the case of 'int32_t' this is supposedly a core C type but it is
quite unknown to the language until you include a particular header.
Who said it was a "core C type"? What does "core C type" even mean?
(It's not mentioned in 6.2.3, "Types".)
But my example highlighted the fact that you can do this:
Point Point;
provided the first Point is a user-defined type defined in an outer
scope. Further:
Point typedef Point; // new scope starts at that 'typedef'
{Point Point;}
Yet again, "Doctor, it hurts when I do this."
The attitude here seems to be, if you can write nonsense in any
language anyway, then why bother making it harder to do so? Let's have
fewer rules and make it easier!
No, that's what the attitude here seems *to you* to be. As usual,
you've misunderstood what everyone else here thinks.
Its a recursive koch fractal using AppleSoft basic.
On 14/06/2026 00:46, Keith Thompson wrote:
Bart <bc@freeuk.com> writes:
On 13/06/2026 13:35, Janis Papanagnou wrote:You seem think that acknowledgement is important. Upthread, you
On 2026-06-13 12:14, tTh wrote:
On 6/13/26 12:03, Bart wrote:Yes. (And I suppose everyone here understands that!)
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?
Thank you for at least acknowledging that.
asked a question. I spent substantial time and effort answering
it. You have not acknowledged that. I don't think you've ever
acnowledged it when I've answered one of your questions. Why is
that?
You seem touchy about this. Sometimes I write considerable amounts
only for people to complete ignore the content, or just snip it. It
happens. I can't remember anyone thanking me for anything.
Regarding your comments about why compound literals look like they do,
it sounded like speculation on your part. Not much for me to say about
it other than putting another POV on some parts.
It still came across as excuses for something that you clearly think
is a trivial matter. I consider cleaner, less cluttered code
important.
(I don't expect acknowledgement from you. I enjoyed writing the
explanation, and I hope that others might benefit from it, or at
least find it interesting.)
[...]
In the case of 'int32_t' this is supposedly a core C type but it isWho said it was a "core C type"? What does "core C type" even mean?
quite unknown to the language until you include a particular header.
(It's not mentioned in 6.2.3, "Types".)
It came up in a thread last year where it was suggested that stdint
types were pretty much of the same rank as 'char short int long'
etc. I'm not going to trawl through of posts to try and find it.
Of course I don't agree that they are a core type; they are usually
typedefs around 'char short' etc.
But my example highlighted the fact that you can do this:Yet again, "Doctor, it hurts when I do this."
Point Point;
provided the first Point is a user-defined type defined in an outer
scope. Further:
Point typedef Point; // new scope starts at that 'typedef'
{Point Point;}
And yet again on my part, why allow it in the first place?
C uses declarations where the type comes first. Now it is more
fashionable for the type to come after the identifier being
defined.
The attitude here seems to be, if you can write nonsense in any
language anyway, then why bother making it harder to do so? Let's have
fewer rules and make it easier!
No, that's what the attitude here seems *to you* to be. As usual,
you've misunderstood what everyone else here thinks.
Countless posts here that people have made suggested exactly that.
Bart <bc@freeuk.com> writes:
Regarding your comments about why compound literals look like they do,
it sounded like speculation on your part. Not much for me to say about
it other than putting another POV on some parts.
I'd say my answer was *informed* speculation, based on the facts
about how compound literals are defined and my knowledge of the
implications of other possible definitions (in particular, that
a version without the type name probably couldn't be made to work
without radical and otherwise unnecessary changes to C). If you
really want to know what the authors of the standard had in mind,
you can search through the committee's published documents as well
as I can. I don't believe that's what you want to know.
Tell me this. Were you really interested in an actual answer to your question, or was it just a rhetorical method to complain yet again
about a feature of C that you don't like?
you wanted an answer. All the evidence suggests that you didn't.
Should I assume that any time you ask a question about C, particularly
about why a feature you dislike is the way it is, that you really don't
care about the answer?
It still came across as excuses for something that you clearly think
is a trivial matter. I consider cleaner, less cluttered code
important.
Explanations, not excuses, for a decision for which there were valid
reasons that you refuse to acknowledge or accept.
(I don't expect acknowledgement from you. I enjoyed writing the
explanation, and I hope that others might benefit from it, or at
least find it interesting.)
[...]
In the case of 'int32_t' this is supposedly a core C type but it isWho said it was a "core C type"? What does "core C type" even mean?
quite unknown to the language until you include a particular header.
(It's not mentioned in 6.2.3, "Types".)
It came up in a thread last year where it was suggested that stdint
types were pretty much of the same rank as 'char short int long'
etc. I'm not going to trawl through of posts to try and find it.
The word "rank" has a specific meaning; I presume that's not what
you meant. If that other person did mean "rank" in that sense,
then it was likely to be a correct statement; if int32_t is a
typedef for int, then it has the same rank as int.
And I suppose I have to admit that my question was rhetorical.
Touch‚.
int32_t is not a "core C type", for any reasonable definition of that
vague phrase. If someone said it is, I disagree, but I also am not
going to trawl through posts to find it.
Of course I don't agree that they are a core type; they are usually
typedefs around 'char short' etc.
But my example highlighted the fact that you can do this:Yet again, "Doctor, it hurts when I do this."
Point Point;
provided the first Point is a user-defined type defined in an outer
scope. Further:
Point typedef Point; // new scope starts at that 'typedef'
{Point Point;}
And yet again on my part, why allow it in the first place?
I could answer that, but I'm nearly certain you would not be
interested in the answer.
C uses declarations where the type comes first. Now it is more
fashionable for the type to come after the identifier being
defined.
It is not "fashionable" in any sense relevant to the topic of this
newsgroup. Yes, different languages have different declaration
syntax. I'll even acknowledge that the declaration syntax of some
other languages has real advantages over C's. But C is what we
try to discuss here.
[...]
The attitude here seems to be, if you can write nonsense in any
language anyway, then why bother making it harder to do so? Let's have >>>> fewer rules and make it easier!
No, that's what the attitude here seems *to you* to be. As usual,
you've misunderstood what everyone else here thinks.
Countless posts here that people have made suggested exactly that.
You're wrong. I won't bother to explain why. I might if you could
convince me that the explanation would be of any interest to you,
but that seems unlikely.
On 14/06/2026 02:26, Keith Thompson wrote:[...]
Tell me this. Were you really interested in an actual answer to your
question, or was it just a rhetorical method to complain yet again
about a feature of C that you don't like?
Why is this such a big deal?
Am 13.06.2026 um 01:52 schrieb Lawrence D?Oliveiro:
On Fri, 12 Jun 2026 06:16:42 +0200, Bonita Montero wrote:
Yes, the allocation of the stack is very expensive. And the
context-switch between threads is a magnitudes more expensive than
switching between two coroutine conexts.
Why should that be? What extra overhead is there in
context-switching between preemptive threads, versus non-preemptive
ones?
Because with threading the context-switch happens inside the kernel.
On Sat, 13 Jun 2026 05:05:23 +0200, Bonita Montero wrote:
Am 13.06.2026 um 01:52 schrieb Lawrence D?Oliveiro:
On Fri, 12 Jun 2026 06:16:42 +0200, Bonita Montero wrote:
Yes, the allocation of the stack is very expensive. And the
context-switch between threads is a magnitudes more expensive than
switching between two coroutine conexts.
Why should that be? What extra overhead is there in
context-switching between preemptive threads, versus non-preemptive
ones?
Because with threading the context-switch happens inside the kernel.
Microsoft Windows problems again?
On Sat, 13 Jun 2026 13:46:55 -0700, Chris M. Thomasson wrote:
Its a recursive koch fractal using AppleSoft basic.
Yes, that was pretty clear. As was the fact that you were able to get
it working, not *because of* your choice of BASIC to write it in, but
*in spite of* that.
On 6/11/2026 5:12 PM, Lawrence D?Oliveiro wrote:
On Thu, 11 Jun 2026 14:18:09 -0700, Chris M. Thomasson wrote:
On 6/10/2026 9:40 PM, Lawrence D?Oliveiro wrote:
For cases where the bottleneck is in the I/O or the network
connection (which is a lot of them), threading is typically
unnecessary. Instead, the popular approach nowadays is to use
coroutines.
Not sure why you say that.
It does tend to be error-prone.
Well, shit happens. :^)
That?s why it is best reserved for CPU-intensive tasks that can
benefit from running a bunch of cores at once.
On 6/13/2026 5:32 PM, Lawrence D?Oliveiro wrote:
On Sat, 13 Jun 2026 13:46:55 -0700, Chris M. Thomasson wrote:
Its a recursive koch fractal using AppleSoft basic.
Yes, that was pretty clear. As was the fact that you were able to
get it working, not *because of* your choice of BASIC to write it
in, but *in spite of* that.
It has current stack space.
So, with a little work it should be workable for continuations.
Microsoft Windows problems? What do you mean? preemptive threads say
POSIX threads are going to have the same issues. Right?
On 6/11/2026 9:06 PM, Chris M. Thomasson wrote:
On 6/11/2026 5:12 PM, Lawrence D?Oliveiro wrote:
On Thu, 11 Jun 2026 14:18:09 -0700, Chris M. Thomasson wrote:
On 6/10/2026 9:40 PM, Lawrence D?Oliveiro wrote:
For cases where the bottleneck is in the I/O or the network
connection (which is a lot of them), threading is typically
unnecessary. Instead, the popular approach nowadays is to use
coroutines.
Not sure why you say that.
It does tend to be error-prone.
Well, shit happens. :^)
Error prone... Well, C is not the lang that takes the corks off the forks:
(Dirty Rotten Scoundrels (1988) - Dinner With Ruprecht Scene (6/12) | Movieclips)
https://youtu.be/SKDX-qJaJ08
rofl!
That?s why it is best reserved for CPU-intensive tasks that can
benefit from running a bunch of cores at once.
| Sysop: | Jacob Catayoc |
|---|---|
| Location: | Pasay City, Metro Manila, Philippines |
| Users: | 4 |
| Nodes: | 4 (0 / 4) |
| Uptime: | 494930:54:31 |
| Calls: | 162 |
| Files: | 568 |
| D/L today: |
14 files (349K bytes) |
| Messages: | 75,011 |