On 11/06/2026 09:21, Bonita Montero wrote:
Am 11.06.2026 um 08:28 schrieb Lawrence DrCOOliveiro:
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.-a There are a wide variety of coroutine implementations in C, with different mixtures of features, limitations, efficiencies, portability and requirements.-a 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 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 DrCOOliveiro:
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.-a 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.
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).-a 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.-a 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.-a 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.-a K&R C, the language from "The C Programming Language", was a huge improvement and standardisation compared to 1973 C.-a 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.-a 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.-a K&R C, the language
from "The C Programming Language", was a huge improvement and
standardisation compared to 1973 C.-a 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.-a K&R C, the language
from "The C Programming Language", was a huge improvement and
standardisation compared to 1973 C.-a 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.-a K&R C, the language
from "The C Programming Language", was a huge improvement and
standardisation compared to 1973 C.-a 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'-a thing which i would like to use
they could even add resizable rrays in fact
int tab[10];
foo()
{
-a 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.-a K&R C, the language
from "The C Programming Language", was a huge improvement and
standardisation compared to 1973 C.-a 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.-a Its heritage goes back 50 years, but it has improved greatly since then.
You don't like C - we know that.-a 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.-a K&R C, the language
from "The C Programming Language", was a huge improvement and
standardisation compared to 1973 C.-a 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.-a Its
heritage goes back 50 years, but it has improved greatly since then.
You don't like C - we know that.-a 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.a 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.-a 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.-a 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
-a rolling their own mini-solutions
* Putting a huge amount of effort into tools that can help detect or get
-a around problems, rather than actually fixing the language. But here,
-a 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:
-a-a-a typedef struct {double x, y;} Point;
-a-a-a Point p = {10, 20};
-a-a-a Point q;
-a-a-a-a-a-a-a-a-a q = (Point){30, 40};
The initialisation of 'p' doesn't need it, so can't you just do this:
-a-a-a-a-a-a-a-a-a 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.
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)
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:
-a #include <stdint.h>
-a int32_t int32_t;
-a int32_t = 0;
and that is just fine; just "don't do it"! In that case, we might as
well allow:
-a 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:
-a-a #include <stdint.h>
-a-a int32_t int32_t;
-a-a int32_t = 0;
and that is just fine; just "don't do it"! In that case, we might as
well allow:
-a-a int int;
Can you understand how crazy the above looks from outside?
-a-a In our technical jargon, we have the perfect acronym to
-a-a describe this kind of programming: GIGO. Look at wikipedia
-a-a for an astounding description of that syndrom.
-a-a 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:
-a-a #include <stdint.h>
-a-a int32_t int32_t;
-a-a int32_t = 0;
and that is just fine; just "don't do it"! In that case, we might as
well allow:
-a-a 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:-a-a 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:
-a-a-a In our technical jargon, we have the perfect acronym to
-a-a-a describe this kind of programming: GIGO. Look at wikipedia
-a-a-a for an astounding description of that syndrom.
-a-a-a 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!")
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:
-a-a #include <stdint.h>
-a-a int32_t int32_t;
-a-a int32_t = 0;
and that is just fine; just "don't do it"! In that case, we might
as well allow:
-a-a 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:
-a-a #include <stdint.h>
-a-a int32_t int32_t;
-a-a int32_t = 0;
and that is just fine; just "don't do it"! In that case, we might
as well allow:
-a-a 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.
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:
-a-a #include <stdint.h>
-a-a int32_t int32_t;
-a-a int32_t = 0;
and that is just fine; just "don't do it"! In that case, we might
as well allow:
-a-a 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?
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};
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:
Seriously? You have a language where you can literally do this:
-a-a #include <stdint.h>
-a-a int32_t int32_t;
-a-a int32_t = 0;
and that is just fine; just "don't do it"! In that case, we might as
well allow:
-a-a int int;
Can you understand how crazy the above looks from outside?
Yes. (And I suppose everyone here understands that!)
Thank you for at least acknowledging 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:-a-a for for in in do ; do : ; done
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.
[...]
Such pieces of code are a result of a programmer's sick brain and
not the problem of a language.
Such pieces of code are 100% *enabled* by the language so, yes, you can blame the language.
These examples are not possible in mine for example,
due to different scoping rules.
[...]
Quite draconian, I know! A programmer can still do 'crazy' stuff, but
they have to work harder.
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!
[...]
On 2026-06-13 15:38, Bart wrote:
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:
Seriously? You have a language where you can literally do this:
-a-a #include <stdint.h>
-a-a int32_t int32_t;
-a-a int32_t = 0;
and that is just fine; just "don't do it"! In that case, we might as >>>>> well allow:
-a-a int int;
Can you understand how crazy the above looks from outside?
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.
Yes. That's something that I (also?) don't think is good language
design. (Many things in "C" I actually consider to be kludges and
quirks; but so what?)
Janis Papanagnou <janis_papanagnou+ng@hotmail.com> writes:
On 2026-06-13 15:38, Bart wrote:
[...]
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.
Yes. That's something that I (also?) don't think is good language
design. (Many things in "C" I actually consider to be kludges and
quirks; but so what?)
Technically, the C language evolved, it wasn't designed per se.
And there are good reasons (backward compatability) for conditioning
support of the fixed size types on inclusion of <stdint.h> rather than building them into the language.
Like it or not, it cannot be changed.
| Sysop: | Amessyroom |
|---|---|
| Location: | Fayetteville, NC |
| Users: | 70 |
| Nodes: | 6 (0 / 6) |
| Uptime: | 39:16:08 |
| Calls: | 948 |
| Calls today: | 2 |
| Files: | 1,325 |
| Messages: | 280,644 |