i think this list should be done maybe
but i would need to compose it
so this post is not yet a list but to open
a topic
two most top annoyances at the moment of my
memory is
I
˙need of predeclarations (this is that i need
to declare a symbol up its usage as it cant be seen down
in code)
ITS TERRIBLE ANNOYING AND USELESS
II
˙no adhoc enums (tags) type - i mean
such i dont need tod efine i just may use it
like
foo('red'); foo('quick');
where in foo
foo(ad_hoc_enum e)
{
˙˙ if(e=='red) ....
}
no definitions just tags
some could say i could use structures
struct red {}
struct quick {}
its not bad idea but i need tod efine it and that is
a problem (besides type problems) i need adhoc
this is so usefull and needed its probably
SECOND TERRIBLE ANNOYANCE
III....
other candidates are
1) that i need to repeat type names foo(floay x, float y, float z)
instedad of foo(float x,y,x)
2) that i need end line with ";" (where newline sign should work
3) that "," operator dont work in many cases
4) & and | should also be used for logical imo
(i would need to rethink if t needs some changes in language and when it ffalls) now
5) *p.s works bad
and yet few things
(i was writing on all this already but i hjust think official list
should be written)
On 06/09/2026 14:45, fir wrote:
i think this list should be done maybe
but i would need to compose it
so this post is not yet a list but to open
a topic
two most top annoyances at the moment of my
memory is
I
˙˙need of predeclarations (this is that i need
to declare a symbol up its usage as it cant be seen down
in code)
ITS TERRIBLE ANNOYING AND USELESS
II
˙˙no adhoc enums (tags) type - i mean
such i dont need tod efine i just may use it
[...]
SECOND TERRIBLE ANNOYANCE
III....
other candidates are
1) that i need to repeat type names foo(floay x, float y, float z)
instedad of foo(float x,y,x)
2) that i need end line with ";" (where newline sign should work
3) that "," operator dont work in many cases
4) & and | should also be used for logical imo
(i would need to rethink if t needs some changes in language and when
it ffalls) now
5) *p.s works bad
and yet few things
(i was writing on all this already but i hjust think official list
should be written)
Yeah, my own list had 100 annoyances.
But then, I also had my own language which fixed ALL OF THEM, and did a
lot more.
With C, I first tried creating a thin syntax wrapper, transpiled with a 300-line script into standard C, but this only dealt with a fraction of them, and required code to be written in a certain way (to avoid needing
a full lexer).
The thing is nobody here can fix it for you.
So, if you don't want to do this work yourself:
* Use C even if it is annoying (it sounds like there are lots of things
you could do but aren't aware of them, so learn the language better).
* Switch languages. Most modern ones allow out of order functions (use a function before it is defined; no declaration needed), plus have lots of other features
On 2026-09-06 17:52, bart wrote:
On 06/09/2026 14:45, fir wrote:
i think this list should be done maybe
but i would need to compose it
so this post is not yet a list but to open
a topic
two most top annoyances at the moment of my
memory is
I
˙˙need of predeclarations (this is that i need
to declare a symbol up its usage as it cant be seen down
in code)
Are you saying you miss the option to do
x = 1.5;
/*
˙˙˙ ... 100 lines of code ...
*/
float x;
On 2026-09-06 17:52, bart wrote:
On 06/09/2026 14:45, fir wrote:
i think this list should be done maybe
but i would need to compose it
so this post is not yet a list but to open
a topic
two most top annoyances at the moment of my
memory is
I
˙˙need of predeclarations (this is that i need
to declare a symbol up its usage as it cant be seen down
in code)
Are you saying you miss the option to do
x = 1.5;
/*
˙˙˙ ... 100 lines of code ...
*/
float x;
Or do you want to resolve *every* entity name by the linker
(without seeing the declaration at the place where it belongs)?
Janis Papanagnou pisze:
On 2026-09-06 17:52, bart wrote:
On 06/09/2026 14:45, fir wrote:
i think this list should be done maybe
but i would need to compose it
so this post is not yet a list but to open
a topic
two most top annoyances at the moment of my
memory is
I
˙˙need of predeclarations (this is that i need
to declare a symbol up its usage as it cant be seen down
in code)
Are you saying you miss the option to do
x = 1.5;
/*
˙˙˙˙ ... 100 lines of code ...
*/
float x;
of course this is a common problem to me i got
something like
int quests_screen;
in one file "screens.c"
and i need an acces to it form another files
but its not avaliable
eventually c could dissalow that in a file but allow that visibility
among files - but c dont understand the concept of files
(which is rather bad) (maybe files just should be considered modules)
* Switch languages. Most modern ones allow out of order functions (use a function before it is defined; no declaration needed), plus have lots of other features
On 07/09/2026 08:37, fir wrote:
Janis Papanagnou pisze:
On 2026-09-06 17:52, bart wrote:
On 06/09/2026 14:45, fir wrote:
i think this list should be done maybe
but i would need to compose it
so this post is not yet a list but to open
a topic
two most top annoyances at the moment of my
memory is
I
˙˙need of predeclarations (this is that i need
to declare a symbol up its usage as it cant be seen down
in code)
Are you saying you miss the option to do
x = 1.5;
/*
˙˙˙˙ ... 100 lines of code ...
*/
float x;
of course this is a common problem to me i got
something like
int quests_screen;
in one file "screens.c"
and i need an acces to it form another files
but its not avaliable
eventually c could dissalow that in a file but allow that visibility
among files - but c dont understand the concept of files
(which is rather bad) (maybe files just should be considered modules)
It sounds like you don't understand C. To solve this particular problem, create a header like this:
screens.h:
˙ extern int quests_screen;˙˙˙˙˙ // shared declaration
In screens.c:
˙ #include "screens.h"
˙ int quests_screen;˙˙˙˙˙˙˙˙˙˙˙˙ // definition (you can initialise here)
In all files you want to use this from, add this line:
˙ #include "screens.h"
That's how it has to work in C. Of course with proper modules, it's
simpler:
In screens.m (my language):
˙ global int quests_screen
In lead module of application:
˙ module screens
Now 'screens_quest' is available in all modules, even without a
qualifier. And you don't even need to submit 'screens.m' to the
compiler; it will find it.
If you need such functionality, then perhaps do as David Brown
suggested, just switch to C++, where your existing C code will still
largely work.
But I doubt whether C++'s newly acquired module scheme is quite as sweet
as mine (however my language uses whole-program compilation; it works differently).
i think this list should be done maybe
but i would need to compose it
so this post is not yet a list but to open
a topic
two most top annoyances at the moment of my
memory is
I
˙need of predeclarations (this is that i need
to declare a symbol up its usage as it cant be seen down
in code)
ITS TERRIBLE ANNOYING AND USELESS
II
˙no adhoc enums (tags) type - i mean
such i dont need tod efine i just may use it
like
foo('red'); foo('quick');
where in foo
foo(ad_hoc_enum e)
{
˙˙ if(e=='red) ....
}
no definitions just tags
some could say i could use structures
struct red {}
struct quick {}
its not bad idea but i need tod efine it and that is
a problem (besides type problems) i need adhoc
this is so usefull and needed its probably
SECOND TERRIBLE ANNOYANCE
III....
other candidates are
1) that i need to repeat type names foo(floay x, float y, float z)
instedad of foo(float x,y,x)
2) that i need end line with ";" (where newline sign should work
3) that "," operator dont work in many cases
4) & and | should also be used for logical imo
(i would need to rethink if t needs some changes in language and when it ffalls) now
5) *p.s works bad
and yet few things
(i was writing on all this already but i hjust think official list
should be written)
On 07/09/2026 12:35, bart wrote:
On 07/09/2026 08:37, fir wrote:
Janis Papanagnou pisze:
On 2026-09-06 17:52, bart wrote:
On 06/09/2026 14:45, fir wrote:
i think this list should be done maybe
but i would need to compose it
so this post is not yet a list but to open
a topic
two most top annoyances at the moment of my
memory is
I
˙˙need of predeclarations (this is that i need
to declare a symbol up its usage as it cant be seen down
in code)
Are you saying you miss the option to do
x = 1.5;
/*
˙˙˙˙ ... 100 lines of code ...
*/
float x;
of course this is a common problem to me i got
something like
int quests_screen;
in one file "screens.c"
and i need an acces to it form another files
but its not avaliable
eventually c could dissalow that in a file but allow that visibility
among files - but c dont understand the concept of files
(which is rather bad) (maybe files just should be considered modules)
It sounds like you don't understand C. To solve this particular
problem, create a header like this:
screens.h:
˙˙ extern int quests_screen;˙˙˙˙˙ // shared declaration
In screens.c:
˙˙ #include "screens.h"
˙˙ int quests_screen;˙˙˙˙˙˙˙˙˙˙˙˙ // definition (you can initialise here)
In all files you want to use this from, add this line:
˙˙ #include "screens.h"
Yes, that's the way to do it.
That's how it has to work in C. Of course with proper modules, it's
simpler:
In screens.m (my language):
˙˙ global int quests_screen
In lead module of application:
˙˙ module screens
Now 'screens_quest' is available in all modules, even without a
qualifier. And you don't even need to submit 'screens.m' to the
compiler; it will find it.
While that is undoubtedly less typing, I'd question it being "proper modules".˙ I would say that a good modules system requires a higher
degree of explicit control and qualification
This kind of implicit
"find stuff automatically" and "import everything" is okay for small programs up to perhaps a few dozen modules
A "proper" modules system can handle
multiple files or modules in a project with the same name (even C can
handle that)
But I doubt whether C++'s newly acquired module scheme is quite as
sweet as mine (however my language uses whole-program compilation; it
works differently).
Presumably your language's modules fit exactly with what you think is
ideal, for your usage.˙ For other people, I suspect C++'s scheme is a
better fit - though since it is made to cover a huge variety of use-
cases, and to fit with an existing language, few people will consider it "perfect" for their own personal needs.
between a one-man language and mainstream languages.I'd be interested in what the C++ would look like for my example above;
On 07/09/2026 08:37, fir wrote:
Janis Papanagnou pisze:
On 2026-09-06 17:52, bart wrote:
On 06/09/2026 14:45, fir wrote:
i think this list should be done maybe
but i would need to compose it
so this post is not yet a list but to open
a topic
two most top annoyances at the moment of my
memory is
I
˙˙need of predeclarations (this is that i need
to declare a symbol up its usage as it cant be seen down
in code)
Are you saying you miss the option to do
x = 1.5;
/*
˙˙˙˙ ... 100 lines of code ...
*/
float x;
of course this is a common problem to me i got
something like
int quests_screen;
in one file "screens.c"
and i need an acces to it form another files
but its not avaliable
eventually c could dissalow that in a file but allow that visibility
among files - but c dont understand the concept of files
(which is rather bad) (maybe files just should be considered modules)
It sounds like you don't understand C. To solve this particular problem, create a header like this:
screens.h:
˙ extern int quests_screen;˙˙˙˙˙ // shared declaration
In screens.c:
˙ #include "screens.h"
˙ int quests_screen;˙˙˙˙˙˙˙˙˙˙˙˙ // definition (you can initialise here)
In all files you want to use this from, add this line:
˙ #include "screens.h"
That's how it has to work in C. Of course with proper modules, it's
simpler:
On 07/09/2026 12:15, David Brown wrote:
On 07/09/2026 12:35, bart wrote:
On 07/09/2026 08:37, fir wrote:
Janis Papanagnou pisze:
On 2026-09-06 17:52, bart wrote:
On 06/09/2026 14:45, fir wrote:
i think this list should be done maybe
but i would need to compose it
so this post is not yet a list but to open
a topic
two most top annoyances at the moment of my
memory is
I
˙˙need of predeclarations (this is that i need
to declare a symbol up its usage as it cant be seen down
in code)
Are you saying you miss the option to do
x = 1.5;
/*
˙˙˙˙ ... 100 lines of code ...
*/
float x;
of course this is a common problem to me i got
something like
int quests_screen;
in one file "screens.c"
and i need an acces to it form another files
but its not avaliable
eventually c could dissalow that in a file but allow that visibility
among files - but c dont understand the concept of files
(which is rather bad) (maybe files just should be considered modules)
It sounds like you don't understand C. To solve this particular
problem, create a header like this:
screens.h:
˙˙ extern int quests_screen;˙˙˙˙˙ // shared declaration
In screens.c:
˙˙ #include "screens.h"
˙˙ int quests_screen;˙˙˙˙˙˙˙˙˙˙˙˙ // definition (you can initialise
here)
In all files you want to use this from, add this line:
˙˙ #include "screens.h"
Yes, that's the way to do it.
That's how it has to work in C. Of course with proper modules, it's
simpler:
In screens.m (my language):
˙˙ global int quests_screen
In lead module of application:
˙˙ module screens
Now 'screens_quest' is available in all modules, even without a
qualifier. And you don't even need to submit 'screens.m' to the
compiler; it will find it.
While that is undoubtedly less typing, I'd question it being "proper
modules".˙ I would say that a good modules system requires a higher
degree of explicit control and qualification
A typical module scheme works like this:
* You have, say, a project of 100 modules
On 06/09/2026 9:45 PM, fir wrote:
i think this list should be done maybe
but i would need to compose it
so this post is not yet a list but to open
a topic
two most top annoyances at the moment of my
memory is
I
˙˙need of predeclarations (this is that i need
to declare a symbol up its usage as it cant be seen down
in code)
ITS TERRIBLE ANNOYING AND USELESS
II
˙˙no adhoc enums (tags) type - i mean
such i dont need tod efine i just may use it
like
foo('red'); foo('quick');
where in foo
foo(ad_hoc_enum e)
{
˙˙˙ if(e=='red) ....
}
no definitions just tags
some could say i could use structures
struct red {}
struct quick {}
its not bad idea but i need tod efine it and that is
a problem (besides type problems) i need adhoc
this is so usefull and needed its probably
SECOND TERRIBLE ANNOYANCE
III....
other candidates are
1) that i need to repeat type names foo(floay x, float y, float z)
instedad of foo(float x,y,x)
2) that i need end line with ";" (where newline sign should work
3) that "," operator dont work in many cases
4) & and | should also be used for logical imo
(i would need to rethink if t needs some changes in language and when
it ffalls) now
5) *p.s works bad
and yet few things
(i was writing on all this already but i hjust think official list
should be written)
Dear fir,
You missed one.˙ This one is my top 0th annoyance in C, but I've learned
to live with it.
6) The * is used for both multiplication and pointer dereferencing.
As we all know, operators should not be overloaded [1], and allowing the compiler makers to arbitrarily overload operators like this is complete-
ly unacceptable behaviour [sic].˙ It's a crying shame the I.S.O. commit-
tee hasn't fixed this yet.
When do you think they'll get to it?˙ In the 406x standard?
If there's one thing Java got right, was to not require a special symbol
for pointer dereferencing at all.˙ Of course, that also meant that most people using Java don't know they're using pointers, and forget to null
them after use, leading to /memory hogs/ now and then.
I have added comp.lang.java to this discussion.
But that's a minor issue, because Java has a great garbage collector.
One that our very own Pythong influencer, Lawrence D'Oliveiro would be
proud of making himself, but it's already there, so he can't make a new
one.
Best wishes, and happy C coding!
[1] I'm looking at you, Lawrence from comp.lang.python!
On 07/09/2026 12:15, David Brown wrote:
On 07/09/2026 12:35, bart wrote:
On 07/09/2026 08:37, fir wrote:
Janis Papanagnou pisze:
On 2026-09-06 17:52, bart wrote:
On 06/09/2026 14:45, fir wrote:
i think this list should be done maybe
but i would need to compose it
so this post is not yet a list but to open
a topic
two most top annoyances at the moment of my
memory is
I
˙˙need of predeclarations (this is that i need
to declare a symbol up its usage as it cant be seen down
in code)
Are you saying you miss the option to do
x = 1.5;
/*
˙˙˙˙ ... 100 lines of code ...
*/
float x;
of course this is a common problem to me i got
something like
int quests_screen;
in one file "screens.c"
and i need an acces to it form another files
but its not avaliable
eventually c could dissalow that in a file but allow that visibility
among files - but c dont understand the concept of files
(which is rather bad) (maybe files just should be considered modules)
It sounds like you don't understand C. To solve this particular
problem, create a header like this:
screens.h:
˙˙ extern int quests_screen;˙˙˙˙˙ // shared declaration
In screens.c:
˙˙ #include "screens.h"
˙˙ int quests_screen;˙˙˙˙˙˙˙˙˙˙˙˙ // definition (you can initialise
here)
In all files you want to use this from, add this line:
˙˙ #include "screens.h"
Yes, that's the way to do it.
That's how it has to work in C. Of course with proper modules, it's
simpler:
In screens.m (my language):
˙˙ global int quests_screen
In lead module of application:
˙˙ module screens
Now 'screens_quest' is available in all modules, even without a
qualifier. And you don't even need to submit 'screens.m' to the
compiler; it will find it.
While that is undoubtedly less typing, I'd question it being "proper
modules".˙ I would say that a good modules system requires a higher
degree of explicit control and qualification
A typical module scheme works like this:
* You have, say, a project of 100 modules
* Each module selectively exports some entities
* Each module selectively imports some subset of the other 99 modules
The result is that each module starts with some rag-tag collection of 'import' statements, each different from any other module, and needing a
lot of maintenance.
Eg. try changing the name of one module, or you decide to import a name
from an module that is not yet part of the import list; or some import
is no longer needed, but you can't easily know that.
I tried such a scheme and hated how messy it was and how much work was involved.
With the current scheme, if the project was actually an unstructured collection of 100 modules, then just one module (the one submitted to
the compiler) would start with 99 'module' statements. All the
information is in one place.
This kind of implicit
"find stuff automatically" and "import everything" is okay for small programs up to perhaps a few dozen modules
Actually mine is a 2-level scheme: a program is a collection of
subprograms, and each subprogram is a chummy set of modules which can
see each other's exported named entities. (That is, functions,
variables, named constants, types, records, enumerations, macros.)
So the lead module A for an application might look like this:
˙ import sys˙˙˙˙˙˙˙˙˙˙ # (usually implicit so not needed)
˙ module b˙˙˙˙˙˙˙˙˙˙˙˙ # files a.m b.m c.m d.m form main prog
˙ module c
˙ module d
˙ import x˙˙˙˙˙˙˙˙˙˙˙˙ # file x.m is lead module of a self-contained
˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙ # subprogram
Module X here may itself consist of several modules, where entities need
the 'export' attribute rather than 'global' to make them visible
outside; this part is hierarchical.
The main program does not need to know these details; just the set of exported entities. If qualification is needed, an exported function F is called as X.F(); it does not use the actual module name, which is opaque.
The whole thing is built like this:
˙ mm a
No makefiles needed or a long list of files. The aims are to keep it
simple, uncluttered and effortless.
A "proper" modules system can handle
multiple files or modules in a project with the same name (even C can handle that)
Files with the same name are always troublesome. In my scheme, since
module and import names also form identifiers, those cannot clash within
the same scope.
In my example 'x' could also contain a module 'b' (it would need to be
in a different folder), but for other reasons, my scheme requires all
module names in an app to be unique.
(The language also other means to encapsulate entities, nested if
needed, and access them via namespaces; I don't consider that to be 'modules', but some languages do. 'Modules' can mean lots of things.)
But I doubt whether C++'s newly acquired module scheme is quite as
sweet as mine (however my language uses whole-program compilation; it
works differently).
Presumably your language's modules fit exactly with what you think is
ideal, for your usage.˙ For other people, I suspect C++'s scheme is a
better fit - though since it is made to cover a huge variety of use-
cases, and to fit with an existing language, few people will consider
it "perfect" for their own personal needs.
Python is a mainstream language and its module scheme seems simple
enough (if not quite as simple as mine!).
˙ That's always the difference
between a one-man language and mainstream languages.I'd be interested in what the C++ would look like for my example above; let's say the main program uses modules A B C D, and the library uses X
Y Z.
So, how that project info is imparted. And if Y exports a function F,
how that is declared, and how it might be called from A for example.
On 07/09/2026 14:55, bart wrote:
A typical module scheme works like this:
* You have, say, a project of 100 modules
* Each module selectively exports some entities
* Each module selectively imports some subset of the other 99 modules
OK so far.
The result is that each module starts with some rag-tag collection of
'import' statements, each different from any other module, and needing
a lot of maintenance.
No.˙ People who write /structured/ code do not do "rag-tag".
When a project is of a size where it is inconvenient to keep track of
all the separate "import" (or "#include", or whatever) statements, you
use a hierarchy.˙ Instead of importing "dns", "udp", "http", etc.,
modules, you import "network".˙ The common "network" module pulls in the sub-modules.˙ You probably also organise things in directories and sub- directories, matching the module layout.˙ It is /structured/.
With the current scheme, if the project was actually an unstructured
collection of 100 modules, then just one module (the one submitted to
the compiler) would start with 99 'module' statements. All the
information is in one place.
The trick is, don't write code that is an unstructured collection of 100 modules.˙ Structure and organise your code.
Files with the same name are always troublesome. In my scheme, since
module and import names also form identifiers, those cannot clash
within the same scope.
In my example 'x' could also contain a module 'b' (it would need to be
in a different folder), but for other reasons, my scheme requires all
module names in an app to be unique.
That is fine for small projects.˙ And of course with a one-man language,
it is not hard to avoid clashes, even when you have a hundred files.
For
bigger projects with multiple developers, and libraries and code from different places, it is unworkable.
I've lost track of the hypothetical project organisation, and this is
not really the right place for a tutorial on the details of C++ modules.
˙However, I can point out one significant difference between C++
modules and, say, Python modules - in C++, the concept of "module" is independent of the concept of "namespace".˙ That means that the fully qualified names used by the importer of a module depends on the
namespaces used, not the module names.˙ (Of course in a well-organised project, there will be clear correlations between module names, file
names, and namespaces.˙ But they don't have to be one-to-one.)
Thanks. Your explanation makes sense.[...]
I can't answer for fir or Bart, of course, but most often when I see
people complaining about order of declaration in C, they are referring primarily to file-scope entities, and primarily functions.˙ Basically,
they want to be able to order their functions top-down (or without any order) rather than bottom-up, without having to add lots of forward declarations for the functions.˙ [...]
On 2026-09-07 09:53, David Brown wrote:
Thanks. Your explanation makes sense.[...]
I can't answer for fir or Bart, of course, but most often when I see
people complaining about order of declaration in C, they are referring
primarily to file-scope entities, and primarily functions.˙ Basically,
they want to be able to order their functions top-down (or without any
order) rather than bottom-up, without having to add lots of forward
declarations for the functions.˙ [...]
Janis
On 07/09/2026 14:33, David Brown wrote:
On 07/09/2026 14:55, bart wrote:
A typical module scheme works like this:
* You have, say, a project of 100 modules
* Each module selectively exports some entities
* Each module selectively imports some subset of the other 99 modules
OK so far.
The result is that each module starts with some rag-tag collection of
'import' statements, each different from any other module, and
needing a lot of maintenance.
No.˙ People who write /structured/ code do not do "rag-tag".
When a project is of a size where it is inconvenient to keep track of
all the separate "import" (or "#include", or whatever) statements, you
use a hierarchy.˙ Instead of importing "dns", "udp", "http", etc.,
modules, you import "network".˙ The common "network" module pulls in
the sub-modules.˙ You probably also organise things in directories and
sub- directories, matching the module layout.˙ It is /structured/.
But it's a pattern I've seen a lot.
In C also, as collections of
#includes; this example is from Lua, a project of only 35 modules, and
from one of its .c files:
˙#include "lprefix.h"
[ snip list of include directives ]
[...]
Files with the same name are always troublesome. [...]
Lots of projects have 100 files or less. [...]
For bigger projects with multiple developers, and libraries and code
from different places, it is unworkable.
Projects that produce one giant, monolithic binary? If multiple binaries
are involved, then each is a separate project.
[...]
On 2026-09-07 17:34, bart wrote:
On 07/09/2026 14:33, David Brown wrote:
On 07/09/2026 14:55, bart wrote:
A typical module scheme works like this:
* You have, say, a project of 100 modules
* Each module selectively exports some entities
* Each module selectively imports some subset of the other 99 modules
OK so far.
The result is that each module starts with some rag-tag collection
of 'import' statements, each different from any other module, and
needing a lot of maintenance.
No.˙ People who write /structured/ code do not do "rag-tag".
When a project is of a size where it is inconvenient to keep track of
all the separate "import" (or "#include", or whatever) statements,
you use a hierarchy.˙ Instead of importing "dns", "udp", "http",
etc., modules, you import "network".˙ The common "network" module
pulls in the sub-modules.˙ You probably also organise things in
directories and sub- directories, matching the module layout.˙ It
is /structured/.
But it's a pattern I've seen a lot.
(Well, what we see in the wild can sometimes make one even sick.)
The question is; how do we handle that (in our own projects, whether
private or professional).
In C also, as collections of #includes; this example is from Lua, a
project of only 35 modules, and from one of its .c files:
˙˙#include "lprefix.h"
[ snip list of include directives ]
It's even worse; given - as mentioned in another part of the thread -
that #includes are costly we often find some means to avoid not only duplicated includes (by #ifndef LABEL, #define LABEL, ..., #endif)
in the header files but also to prevent accessing the header file in
the first place (by #ifndef LABEL, #include <label.h>, #endif). That
makes such C/C++ code rather messy, IMO. (And makes one appreciate
languages with an inherent good modularization method yet more.)
[...]
Files with the same name are always troublesome. [...]
Unless (if the used language doesn't support any inherent means) you
take organizational precautions to alleviate that situation.
Lots of projects have 100 files or less. [...]
While I can confirm such a magnitude for my personal projects that's
not the magnitude of files we worked with in our professional project contexts. Hint: large projects are themselves, usually hierarchically, structured (not only the code).
that's
not the magnitude of files we worked with in our professional project contexts.
(But I see below that you have your very own view of what you think is
a "project" and see how you organize it. You'll know what suits you.)
For bigger projects with multiple developers, and libraries and code
from different places, it is unworkable.
Projects that produce one giant, monolithic binary? If multiple
binaries are involved, then each is a separate project.
(You may defined that so if you feel that to be right for your cases.)
Generally projects and binaries are not directly 1-to-1 related as you
seem to believe.
On 07/09/2026 23:50, Janis Papanagnou wrote:
On 2026-09-07 17:34, bart wrote:
On 07/09/2026 14:33, David Brown wrote:
On 07/09/2026 14:55, bart wrote:
A typical module scheme works like this:OK so far.
* You have, say, a project of 100 modules
* Each module selectively exports some entities
* Each module selectively imports some subset of the other 99 modules >>>>
The result is that each module starts with some rag-tag collection
of 'import' statements, each different from any other module, and
needing a lot of maintenance.
No.˙ People who write /structured/ code do not do "rag-tag".
When a project is of a size where it is inconvenient to keep track
of all the separate "import" (or "#include", or whatever)
statements, you use a hierarchy.˙ Instead of importing "dns", "udp",
"http", etc., modules, you import "network".˙ The common "network"
module pulls in the sub-modules.˙ You probably also organise things
in directories and sub- directories, matching the module layout.˙ It
is /structured/.
But it's a pattern I've seen a lot.
(Well, what we see in the wild can sometimes make one even sick.)
The question is; how do we handle that (in our own projects, whether
private or professional).
In C also, as collections of #includes; this example is from Lua, a
project of only 35 modules, and from one of its .c files:
˙˙#include "lprefix.h"
[ snip list of include directives ]
It's even worse; given - as mentioned in another part of the thread -
that #includes are costly we often find some means to avoid not only
duplicated includes (by #ifndef LABEL, #define LABEL, ..., #endif)
in the header files but also to prevent accessing the header file in
the first place (by #ifndef LABEL, #include <label.h>, #endif). That
makes such C/C++ code rather messy, IMO. (And makes one appreciate
languages with an inherent good modularization method yet more.)
The duplication is a problem. If 50 modules each includes the header
files for a library such as SDL2, then a full build means a scanning the headers 50 times, which means 4000 header files (80 unique) and 2.5M
lines of code (50K unique).
I have suggested before that this can be mitigated, since such a header format is needlessly sprawling when used in a production environment
(that is, by people who are /using/ the library and not developing it).
This particular set of headers can be condensed from 80 headers/50Kloc
to one header/3Kloc, where the target platform is known.
There is still duplication but now it is scanning only 50 header files
(1 unique) and 150Kloc (3K unique), so should be brisker. And those
other mitigations can still be applied.
[...]
Files with the same name are always troublesome. [...]
Unless (if the used language doesn't support any inherent means) you
take organizational precautions to alleviate that situation.
It's messy anyway. Searching for include files in C is implementation defined. If the compiler is given a set of relative include paths to
search in some order, then it will take the first 'file.h' it sees.
If that has been deleted or renamed, then it may find a 'file.h'
elsewhere, but the wrong one. You hope that it will generate some
errors. Or maybe it you submitted the search paths in the wrong order.
Lots of projects have 100 files or less. [...]
While I can confirm such a magnitude for my personal projects that's
not the magnitude of files we worked with in our professional project
contexts. Hint: large projects are themselves, usually hierarchically,
structured (not only the code).
I work with three levels of a project:
* A single EXE may import external DLL/shared libraries which in turn
import others, so a hierarchy. In this case, each EXE/DLL file, which is
a single binary, would represent a whole project for my
language/compiler if it was my source code
* Within a single EXE/DLL program, my 'subprograms' have their own hierarchy, usually simple
* But within each subprogram, the module structure is flat, by design.
(You will surely have seen projects that uses large numbers of tiny
files, with perhaps one function in each. There is clearly little
hierarchy there.)
that's
not the magnitude of files we worked with in our professional project contexts.
So, what are you saying: that a simple module scheme stops working at a certain scale? I'm saying that VERY MANY applications and libraries are
at a scale where such a scheme would work.
Including most open source C programs I've tried to build, and failed, because the build process was so complex and/or Linux-centric.
(But I see below that you have your very own view of what you think is
a "project" and see how you organize it. You'll know what suits you.)
For bigger projects with multiple developers, and libraries and code
from different places, it is unworkable.
Projects that produce one giant, monolithic binary? If multiple
binaries are involved, then each is a separate project.
(You may defined that so if you feel that to be right for your cases.)
Generally projects and binaries are not directly 1-to-1 related as you
seem to believe.
So what do you call that part of a project which does yield a single
binary?
It's that single binary, comprised from so many individual source files
and that use some specific, existing shared libraries, which is what my whole-program language+compiler addresses.
It is also what a big chunk of a C makefile is about, and such a tool
would eliminate that part of it.
One of the things I avoid in C# is a nasty makefile, and generally
having to tool around in Unix. That is all taken care of by the C#
compiler included in the suite I use to generate my programs.
On 07/09/2026 14:33, David Brown wrote:
On 07/09/2026 14:55, bart wrote:
A typical module scheme works like this:
* You have, say, a project of 100 modules
* Each module selectively exports some entities
* Each module selectively imports some subset of the other 99 modules
OK so far.
The result is that each module starts with some rag-tag collection of
'import' statements, each different from any other module, and needing
a lot of maintenance.
No.˙ People who write /structured/ code do not do "rag-tag".
When a project is of a size where it is inconvenient to keep track of
all the separate "import" (or "#include", or whatever) statements, you
use a hierarchy.˙ Instead of importing "dns", "udp", "http", etc.,
modules, you import "network".˙ The common "network" module pulls in the
sub-modules.˙ You probably also organise things in directories and sub-
directories, matching the module layout.˙ It is /structured/.
But it's a pattern I've seen a lot. In C also, as collections of
#includes; this example is from Lua, a project of only 35 modules, and
from one of its .c files:
#include "lprefix.h"
#include <float.h>
#include <limits.h>
#include <math.h>
#include <stdlib.h>
#include "lua.h"
#include "lcode.h"
#include "ldebug.h"
#include "ldo.h"
#include "lgc.h"
#include "llex.h"
#include "lmem.h"
#include "lobject.h"
#include "lopcodes.h"
#include "lparser.h"
#include "lstring.h"
#include "ltable.h"
#include "lvm.h"
Every file has a different set. In all, there are 28K lines of C code
among the .c files, and there are 466 #include lines. That is similar to
the maintenance nightmare where each file imports a particular set of modules.
On 07/09/2026 23:50, Janis Papanagnou wrote:[ big snip ]
On 2026-09-07 17:34, bart wrote:
On 07/09/2026 14:33, David Brown wrote:
On 07/09/2026 14:55, bart wrote:
Files with the same name are always troublesome. [...]
Unless (if the used language doesn't support any inherent means) you
take organizational precautions to alleviate that situation.
It's messy anyway. Searching for include files in C is implementation defined. If the compiler is given a set of relative include paths to
search in some order, then it will take the first 'file.h' it sees.
If that has been deleted or renamed, then it may find a 'file.h'
elsewhere, but the wrong one. You hope that it will generate some
errors. Or maybe it you submitted the search paths in the wrong order.
[...]
I work with three levels of a project:
* A single EXE may import external DLL/shared libraries which in turn
import others, so a hierarchy. In this case, each EXE/DLL file, which is
a single binary, would represent a whole project for my language/
compiler if it was my source code
* Within a single EXE/DLL program, my 'subprograms' have their own hierarchy, usually simple
* But within each subprogram, the module structure is flat, by design.
(You will surely have seen projects that uses large numbers of tiny
files, with perhaps one function in each. There is clearly little
hierarchy there.)
that's
not the magnitude of files we worked with in our professional project contexts.
So, what are you saying: that a simple module scheme stops working at a certain scale? I'm saying that VERY MANY applications and libraries are
at a scale where such a scheme would work.
Including most open source C programs I've tried to build, and failed, because the build process was so complex and/or Linux-centric.
(But I see below that you have your very own view of what you think is
a "project" and see how you organize it. You'll know what suits you.)
For bigger projects with multiple developers, and libraries and code
from different places, it is unworkable.
Projects that produce one giant, monolithic binary? If multiple
binaries are involved, then each is a separate project.
(You may defined that so if you feel that to be right for your cases.)
Generally projects and binaries are not directly 1-to-1 related as you
seem to believe.
So what do you call that part of a project which does yield a single
binary?
It's that single binary, comprised from so many individual source files
and that use some specific, existing shared libraries, which is what my whole-program language+compiler addresses.
It is also what a big chunk of a C makefile is about, and such a tool
would eliminate that part of it.
It's even worse; given - as mentioned in another part of the thread -
that #includes are costly we often find some means to avoid not only duplicated includes (by #ifndef LABEL, #define LABEL, ..., #endif)
in the header files but also to prevent accessing the header file in
the first place (by #ifndef LABEL, #include <label.h>, #endif). That
makes such C/C++ code rather messy, IMO. (And makes one appreciate
languages with an inherent good modularization method yet more.)
i think this list should be done maybe
but i would need to compose it
so this post is not yet a list but to open
a topic
two most top annoyances at the moment of my
memory is
I
˙need of predeclarations (this is that i need
to declare a symbol up its usage as it cant be seen down
in code)
ITS TERRIBLE ANNOYING AND USELESS
II
˙no adhoc enums (tags) type - i mean
such i dont need tod efine i just may use it
like
foo('red'); foo('quick');
where in foo
foo(ad_hoc_enum e)
{
˙˙ if(e=='red) ....
}
no definitions just tags
some could say i could use structures
struct red {}
struct quick {}
its not bad idea but i need tod efine it and that is
a problem (besides type problems) i need adhoc
this is so usefull and needed its probably
SECOND TERRIBLE ANNOYANCE
III....
other candidates are
1) that i need to repeat type names foo(floay x, float y, float z)
instedad of foo(float x,y,x)
2) that i need end line with ";" (where newline sign should work
3) that "," operator dont work in many cases
4) & and | should also be used for logical imo
(i would need to rethink if t needs some changes in language and when it ffalls) now
5) *p.s works bad
and yet few things
(i was writing on all this already but i hjust think official list
should be written)
6) major annoyance is lack of such functions as sign abs max min (fsign
fabs fmax fmin) and maybe some more (swap) in language standard as
operators
=b //for max
bart <bc@freeuk.com> wrote:
On 07/09/2026 14:33, David Brown wrote:
On 07/09/2026 14:55, bart wrote:
A typical module scheme works like this:
* You have, say, a project of 100 modules
* Each module selectively exports some entities
* Each module selectively imports some subset of the other 99 modules
OK so far.
The result is that each module starts with some rag-tag collection of
'import' statements, each different from any other module, and needing >>>> a lot of maintenance.
No.˙ People who write /structured/ code do not do "rag-tag".
When a project is of a size where it is inconvenient to keep track of
all the separate "import" (or "#include", or whatever) statements, you
use a hierarchy.˙ Instead of importing "dns", "udp", "http", etc.,
modules, you import "network".˙ The common "network" module pulls in the >>> sub-modules.˙ You probably also organise things in directories and sub-
directories, matching the module layout.˙ It is /structured/.
But it's a pattern I've seen a lot. In C also, as collections of
#includes; this example is from Lua, a project of only 35 modules, and
from one of its .c files:
#include "lprefix.h"
#include <float.h>
#include <limits.h>
#include <math.h>
#include <stdlib.h>
#include "lua.h"
#include "lcode.h"
#include "ldebug.h"
#include "ldo.h"
#include "lgc.h"
#include "llex.h"
#include "lmem.h"
#include "lobject.h"
#include "lopcodes.h"
#include "lparser.h"
#include "lstring.h"
#include "ltable.h"
#include "lvm.h"
Every file has a different set. In all, there are 28K lines of C code
among the .c files, and there are 466 #include lines. That is similar to
the maintenance nightmare where each file imports a particular set of
modules.
The organization looks sensible to me.
Given that #include lines
are less than 2% of total and are likely to change very infrequently
I see no maintennce problem.
However, if that bothers you, in
each file of your project you can put
#include "proj.h"
and put all needed includes in inside 'proj.h'. I you choose
good name you will never need to change it so maintenance cost
of '#include "proj.h"' will be close to 0. AFAICS maintenance
cost of 'proj.h' will be very similar to maintenance cost of
your module listing.
C gives you choice: you can have detailed control of what is
imported at cost of writing a lot of '#include' lines or you
can have common header which includes "everthing". With external
tools you can even automate maintanence of includes (say
automatially force any C file in a directory to include all
.h files in the same directory). You implemented a specific
way which you like. But if developers want something different
(as apparently Lua developers want) your compiler (if they
decide to use it) will force on them your way.
fir pisze:
6) major annoyance is lack of such functions as sign abs max min
(fsign fabs fmax fmin) and maybe some more (swap) in language standard
as operators
if such thing as a<b return logical value there should be something
(some operator) that returns˙ the loewr one in place (somewhat by
analogy loke a+2 vs a+=2
i dont know which operator hovever
maybe something like
a=<b˙ //for min
=b //for max
though = eems unfortunate so maybe some other signs here
maybe
a(<)b˙˙ // for min
or something
On 08/09/2026 13:09, fir wrote:
fir pisze:
6) major annoyance is lack of such functions as sign abs max min
(fsign fabs fmax fmin) and maybe some more (swap) in language
standard as operators
if such thing as a<b return logical value there should be something
(some operator) that returns˙ the loewr one in place (somewhat by
analogy loke a+2 vs a+=2
i dont know which operator hovever
maybe something like
a=<b˙ //for min
=b //for max
though = eems unfortunate so maybe some other signs here
maybe
a(<)b˙˙ // for min
or something
gcc had "a <? b" and "a >? b" as minimum and maximum operators, as
extensions in C.˙ They were removed in gcc 4 as they were almost never
used.˙ Operators are only really appropriate for things that are used
often, otherwise they are too unfamiliar to too many people.
It would make a lot more sense to have "min" and "max" as functions in
the standard library.˙ But naming them could be an issue - far too many existing bodies of code already have macros or functions called "min"
and "max".˙ Maybe "stdc_min" and "stdc_max" could be used?
But this really is not something to get worked up about.˙ If it bothers
you, make a header "fir.h" that has these functions in them and use it
in your code.
I also recommend you add these to the file :
#define ? =
#define ? ==
#define ? *
#define ? *
Then instead of boring and easily misunderstood C code like this :
˙˙˙˙c = a * *p == 10;
you can now write clear and obvious code :
˙˙˙˙c ? a ? ?b ? 10;
(Maybe you can find a different Unicode letter that is closer to the one
you wanted - this one has the "hook" on the wrong side.)
Of course, you'll need a good Unicode font to see all these.
David Brown pisze:
On 08/09/2026 13:09, fir wrote:
fir pisze:
6) major annoyance is lack of such functions as sign abs max min
(fsign fabs fmax fmin) and maybe some more (swap) in language
standard as operators
if such thing as a<b return logical value there should be something
(some operator) that returns˙ the loewr one in place (somewhat by
analogy loke a+2 vs a+=2
i dont know which operator hovever
maybe something like
a=<b˙ //for min
=b //for max
though = eems unfortunate so maybe some other signs here
maybe
a(<)b˙˙ // for min
or something
gcc had "a <? b" and "a >? b" as minimum and maximum operators, as
those are good like for returning logical values
4<?5 seems should write 1 instead of 4
i dont know - maybe ? should just return logical value?
as in - funny - in natural language when you ask a question you cast to true/false ;c
if so a<2 could say have no sense/answer (be a hipotesis) and ? would eventually cast it to true/false
its kinda interesting idea...
for example it combines with idea to add it at end of function name
foo? boo˙ //cal foo if true then boo
a<b could eventually also yeild to min but maybe as a side efect
thsi problems need to be more deeply rethinked yet
extensions in C.˙ They were removed in gcc 4 as they were almost neverim not using macros
used.˙ Operators are only really appropriate for things that are used
often, otherwise they are too unfamiliar to too many people.
It would make a lot more sense to have "min" and "max" as functions in
the standard library.˙ But naming them could be an issue - far too
many existing bodies of code already have macros or functions called
"min" and "max".˙ Maybe "stdc_min" and "stdc_max" could be used?
But this really is not something to get worked up about.˙ If it
bothers you, make a header "fir.h" that has these functions in them
and use it in your code.
I also recommend you add these to the file :
#define ? =
#define ? ==
#define ? *
#define ? *
Then instead of boring and easily misunderstood C code like this :
˙˙˙˙˙c = a * *p == 10;
you can now write clear and obvious code :
˙˙˙˙˙c ? a ? ?b ? 10;
(Maybe you can find a different Unicode letter that is closer to the
one you wanted - this one has the "hook" on the wrong side.)
Of course, you'll need a good Unicode font to see all these.
fir pisze:
5) *p.s works bad
and yet few things
6) major annoyance is lack of such functions as sign abs max min (fsign
fabs fmax fmin) and maybe some more (swap) in language standard as
operators
next annoyance is lack of something like
int x = 2000;
x.hi; //i mean if x is 32 bit then hi is higher 16 bitshort and lo is
lower short (maybe unsigned sghort)
x.lo;
x.hi.hi; //higher byte of higher short
x.hi.lo;
it would make a lot of codes who need to unpack bytes nicer and possibly faster
also it could maybe work with˙ floats/doubles
float f = -13.888;
f.sign; //sign
f.exponent; //exponent
f.significand;
f.int; //integral part
f.fract; //fraction part
i.mod; //absolute value
and so on (amy be expanded for builtin complex numbers )
but abstracting from the syntax - becouse its only idea not proposal of syntax (those .filed names would collide wih structure fields etc)
but lack (if ths so called "unpacking") of it is annoyance
fir pisze:
David Brown pisze:
On 08/09/2026 13:09, fir wrote:
fir pisze:
6) major annoyance is lack of such functions as sign abs max min
(fsign fabs fmax fmin) and maybe some more (swap) in language
standard as operators
if such thing as a<b return logical value there should be something
(some operator) that returns˙ the loewr one in place (somewhat by
analogy loke a+2 vs a+=2
i dont know which operator hovever
maybe something like
a=<b˙ //for min
=b //for max
though = eems unfortunate so maybe some other signs here
maybe
a(<)b˙˙ // for min
or something
gcc had "a <? b" and "a >? b" as minimum and maximum operators, as
those are good like for returning logical values
4<?5 seems should write 1 instead of 4
i dont know - maybe ? should just return logical value?
as in - funny - in natural language when you ask a question you cast to
true/false ;c
if so a<2 could say have no sense/answer (be a hipotesis) and ? would
eventually cast it to true/false
ye i thing it may have a sense to treat a>3 as a hipothesis
so it probably man it shouldnt be used as max so maybe min max most
natural is arrows up and down
˙c=a?b
˙d=a?b
it seem possibly anough good
(here by = i mean assign but it could also be a hipothesis for equality
if there would be this assign sign)
its kinda interesting idea...
for example it combines with idea to add it at end of function name
foo? boo˙ //cal foo if true then boo
a<b could eventually also yeild to min but maybe as a side efect
thsi problems need to be more deeply rethinked yet
extensions in C.˙ They were removed in gcc 4 as they were almostim not using macros
never used.˙ Operators are only really appropriate for things that
are used often, otherwise they are too unfamiliar to too many people.
It would make a lot more sense to have "min" and "max" as functions
in the standard library.˙ But naming them could be an issue - far too
many existing bodies of code already have macros or functions called
"min" and "max".˙ Maybe "stdc_min" and "stdc_max" could be used?
But this really is not something to get worked up about.˙ If it
bothers you, make a header "fir.h" that has these functions in them
and use it in your code.
I also recommend you add these to the file :
#define ? =
#define ? ==
#define ? *
#define ? *
Then instead of boring and easily misunderstood C code like this :
˙˙˙˙˙c = a * *p == 10;
you can now write clear and obvious code :
˙˙˙˙˙c ? a ? ?b ? 10;
(Maybe you can find a different Unicode letter that is closer to the
one you wanted - this one has the "hook" on the wrong side.)
Of course, you'll need a good Unicode font to see all these.
On 08/09/2026 11:59, fir wrote:
fir pisze:
5) *p.s works bad
You need either (*p).s here or p->s
and yet few things
6) major annoyance is lack of such functions as sign abs max min
(fsign fabs fmax fmin) and maybe some more (swap) in language standard
as operators
My language has all of 'sign abs min max' built-in and overloaded for
all numeric types, and 'swap' for any type.
I agree that these should be fundamental types at this level of
language, and not simply implemented abs/labs/llabs/fabs functions which need some header. (Which also requires an optimising compiler to turn
them into inline code.)
next annoyance is lack of something like
int x = 2000;
x.hi; //i mean if x is 32 bit then hi is higher 16 bitshort and lo is
lower short (maybe unsigned sghort)
x.lo;
x.hi.hi; //higher byte of higher short
x.hi.lo;
I have some of this stuff (x.msb, x.lsword etc), but it also has more general bit-indexing, for example x.[24..31] for x.hi.hi, for both extracting and inserting.
Note that x.hi.hi probably wouldn't work as you expect: x.hi (when int
is 32 bits) will yield a 16-bit value that is itself sign-extended to 32 bits. Then applying .hi again will yield the top half of that new value, either all 0s or all 1s.
it would make a lot of codes who need to unpack bytes nicer and
possibly faster
At one time I also had x.byte[i] (i is 0..7 for 64 bits, to extract - or inject - the i'th byte), x.u16[i] etc, but those were dropped.
Nobody cares about this in C because you can trivially write macros to
do it.
also it could maybe work with˙ floats/doubles
float f = -13.888;
f.sign; //sign
This would be covered by sign(f) mentioned above, although that will
yield -1, 0, 1 rather than 1/0 for negative/positive. Which one do you
want? If the latter, what should it return for -0.0?
f.exponent; //exponent
In what form will that be? For typical doubles, it will be stored as a power-of-two offset exponent 0 to 2047; not so useful.
Otherwise you can try log10(f) for a decimal exponent.
f.significand;
What that does that mean, the mantissa?
f.int; //integral part
So (3.142).int means 3, or 3.0? What about (1e30).int?
In C you can use (int)f for suitable magnitudes.
f.fract; //fraction part
fmod(f, 1) can do that. This stuff can't easily be done with just bit-shuffling.
i.mod; //absolute value
And this is just fabs()
and so on (amy be expanded for builtin complex numbers )
but abstracting from the syntax - becouse its only idea not proposal
of syntax (those .filed names would collide wih structure fields etc)
but lack (if ths so called "unpacking") of it is annoyance
There are any number of ways to do such unpacking in C, which involve
macros or functions. But your spec doesn't have enough thought behind it
and sounds like idle speculation.
On 08/09/2026 14:49, fir wrote:
fir pisze:
David Brown pisze:
On 08/09/2026 13:09, fir wrote:
fir pisze:
6) major annoyance is lack of such functions as sign abs max min
(fsign fabs fmax fmin) and maybe some more (swap) in language
standard as operators
if such thing as a<b return logical value there should be something
(some operator) that returns˙ the loewr one in place (somewhat by
analogy loke a+2 vs a+=2
i dont know which operator hovever
maybe something like
a=<b˙ //for min
=b //for max
though = eems unfortunate so maybe some other signs here
maybe
a(<)b˙˙ // for min
or something
gcc had "a <? b" and "a >? b" as minimum and maximum operators, as
those are good like for returning logical values
4<?5 seems should write 1 instead of 4
i dont know - maybe ? should just return logical value?
as in - funny - in natural language when you ask a question you cast to
true/false ;c
if so a<2 could say have no sense/answer (be a hipotesis) and ? would
eventually cast it to true/false
ye i thing it may have a sense to treat a>3 as a hipothesis
so it probably man it shouldnt be used as max so maybe min max most
natural is arrows up and down
˙˙c=a?b
˙˙d=a?b
it seem possibly anough good
(here by = i mean assign but it could also be a hipothesis for
equality if there would be this assign sign)
This will be the last time (and only because I think it is fun, not
because I think it is a good idea!) - you can get what you want, today,
with C++ and macros.
struct Min_helper { };
template<typename T>
struct Min_doer { T v; };
template<typename T>
constexpr auto operator + (T x, Min_helper) { return Min_doer(x); } template<typename T>
constexpr auto operator + (Min_doer<T> x, T y)
˙˙˙˙˙˙˙˙ { return (x.v < y) ? x.v : y; }
constexpr auto min_helper = Min_helper {};
#define ? +min_helper+
int x = 10 ? 20;
double y = 352.56 ? 42.5;
Pick a different Unicode letter than ? if you want.˙ Making "10 ? 3.2"
work correctly is an exercise left for c.l.c++.
Much of what you say you want is entirely possible, today, using a
language that can be used mostly like C.˙ You don't have to design a new language, or implement your own compiler - you just have to change your
file endings to ".cpp" instead of ".c", define a few classes, functions,
and user-defined literals, and some macros with Unicode letters of your liking.˙ I feel entirely confident that you will not do this - you'd
rather rant incomprehensibly about how inferior the C standards
committee are compared to your own genius.˙ But for anyone who looks at
APL and thinks "that's too simple", the examples I've given show how to
make your own secret programming language!
its kinda interesting idea...
for example it combines with idea to add it at end of function name
foo? boo˙ //cal foo if true then boo
a<b could eventually also yeild to min but maybe as a side efect
thsi problems need to be more deeply rethinked yet
extensions in C.˙ They were removed in gcc 4 as they were almostim not using macros
never used.˙ Operators are only really appropriate for things that
are used often, otherwise they are too unfamiliar to too many people.
It would make a lot more sense to have "min" and "max" as functions
in the standard library.˙ But naming them could be an issue - far
too many existing bodies of code already have macros or functions
called "min" and "max".˙ Maybe "stdc_min" and "stdc_max" could be used? >>>>
But this really is not something to get worked up about.˙ If it
bothers you, make a header "fir.h" that has these functions in them
and use it in your code.
I also recommend you add these to the file :
#define ? =
#define ? ==
#define ? *
#define ? *
Then instead of boring and easily misunderstood C code like this :
˙˙˙˙˙c = a * *p == 10;
you can now write clear and obvious code :
˙˙˙˙˙c ? a ? ?b ? 10;
(Maybe you can find a different Unicode letter that is closer to the
one you wanted - this one has the "hook" on the wrong side.)
Of course, you'll need a good Unicode font to see all these.
On 08/09/2026 14:49, fir wrote:
fir pisze:
David Brown pisze:
On 08/09/2026 13:09, fir wrote:
fir pisze:
6) major annoyance is lack of such functions as sign abs max min
(fsign fabs fmax fmin) and maybe some more (swap) in language
standard as operators
if such thing as a<b return logical value there should be something
(some operator) that returns˙ the loewr one in place (somewhat by
analogy loke a+2 vs a+=2
i dont know which operator hovever
maybe something like
a=<b˙ //for min
=b //for max
though = eems unfortunate so maybe some other signs here
maybe
a(<)b˙˙ // for min
or something
gcc had "a <? b" and "a >? b" as minimum and maximum operators, as
those are good like for returning logical values
4<?5 seems should write 1 instead of 4
i dont know - maybe ? should just return logical value?
as in - funny - in natural language when you ask a question you cast to
true/false ;c
if so a<2 could say have no sense/answer (be a hipotesis) and ? would
eventually cast it to true/false
ye i thing it may have a sense to treat a>3 as a hipothesis
so it probably man it shouldnt be used as max so maybe min max most
natural is arrows up and down
˙˙c=a?b
˙˙d=a?b
it seem possibly anough good
(here by = i mean assign but it could also be a hipothesis for
equality if there would be this assign sign)
This will be the last time (and only because I think it is fun, not
because I think it is a good idea!) - you can get what you want, today,
with C++ and macros.
struct Min_helper { };
template<typename T>
struct Min_doer { T v; };
template<typename T>
constexpr auto operator + (T x, Min_helper) { return Min_doer(x); } template<typename T>
constexpr auto operator + (Min_doer<T> x, T y)
˙˙˙˙˙˙˙˙ { return (x.v < y) ? x.v : y; }
constexpr auto min_helper = Min_helper {};
#define ? +min_helper+
int x = 10 ? 20;
double y = 352.56 ? 42.5;
Pick a different Unicode letter than ? if you want.˙ Making "10 ? 3.2"
work correctly is an exercise left for c.l.c++.
Much of what you say you want is entirely possible, today, using a
language that can be used mostly like C.˙ You don't have to design a new language, or implement your own compiler - you just have to change your
file endings to ".cpp" instead of ".c", define a few classes, functions,
and user-defined literals, and some macros with Unicode letters of your liking.˙ I feel entirely confident that you will not do this - you'd
rather rant incomprehensibly about how inferior the C standards
committee are compared to your own genius.˙ But for anyone who looks at
APL and thinks "that's too simple", the examples I've given show how to
make your own secret programming language!
On 07/09/2026 23:50, Janis Papanagnou wrote:
It's even worse; given - as mentioned in another part of the thread -
that #includes are costly we often find some means to avoid not only
duplicated includes (by #ifndef LABEL, #define LABEL, ..., #endif)
in the header files but also to prevent accessing the header file in
the first place (by #ifndef LABEL, #include <label.h>, #endif). That
makes such C/C++ code rather messy, IMO. (And makes one appreciate
languages with an inherent good modularization method yet more.)
The duplication is a problem. If 50 modules each includes the header
files for a library such as SDL2, then a full build means a scanning the >headers 50 times, which means 4000 header files (80 unique) and 2.5M
lines of code (50K unique).
David Brown wrote:
On 08/09/2026 14:49, fir wrote:
fir pisze:
David Brown pisze:
On 08/09/2026 13:09, fir wrote:
fir pisze:
6) major annoyance is lack of such functions as sign abs max min >>>>>>> (fsign fabs fmax fmin) and maybe some more (swap) in language
standard as operators
if such thing as a<b return logical value there should be something >>>>>> (some operator) that returns˙ the loewr one in place (somewhat by >>>>>> analogy loke a+2 vs a+=2
i dont know which operator hovever
maybe something like
a=<b˙ //for min
=b //for max
though = eems unfortunate so maybe some other signs here
maybe
a(<)b˙˙ // for min
or something
gcc had "a <? b" and "a >? b" as minimum and maximum operators, as
those are good like for returning logical values
4<?5 seems should write 1 instead of 4
i dont know - maybe ? should just return logical value?
as in - funny - in natural language when you ask a question you cast to >>>> true/false ;c
if so a<2 could say have no sense/answer (be a hipotesis) and ?
would eventually cast it to true/false
ye i thing it may have a sense to treat a>3 as a hipothesis
so it probably man it shouldnt be used as max so maybe min max most
natural is arrows up and down
˙˙c=a?b
˙˙d=a?b
it seem possibly anough good
(here by = i mean assign but it could also be a hipothesis for
equality if there would be this assign sign)
This will be the last time (and only because I think it is fun, not
because I think it is a good idea!) - you can get what you want,
today, with C++ and macros.
struct Min_helper { };
template<typename T>
struct Min_doer { T v; };
template<typename T>
constexpr auto operator + (T x, Min_helper) { return Min_doer(x); }
template<typename T>
constexpr auto operator + (Min_doer<T> x, T y)
˙˙˙˙˙˙˙˙˙ { return (x.v < y) ? x.v : y; }
constexpr auto min_helper = Min_helper {};
#define ? +min_helper+
int x = 10 ? 20;
double y = 352.56 ? 42.5;
Pick a different Unicode letter than ? if you want.˙ Making "10 ? 3.2"
work correctly is an exercise left for c.l.c++.
Much of what you say you want is entirely possible, today, using a
language that can be used mostly like C.˙ You don't have to design a
new language, or implement your own compiler - you just have to change
your file endings to ".cpp" instead of ".c", define a few classes,
functions, and user-defined literals, and some macros with Unicode
letters of your liking.˙ I feel entirely confident that you will not
do this - you'd rather rant incomprehensibly about how inferior the C
standards committee are compared to your own genius.˙ But for anyone
who looks at APL and thinks "that's too simple", the examples I've
given show how to make your own secret programming language!
I don't understand why it's okay to talk about C++ here but not C#? C#
is way better than C++.
The only reason people still use C++ is because of its overall speed
from what I can tell. Or else they haven't been cultured enough to experience C# yet.
What can be done to improve C#'s overall speed?
bart <bc@freeuk.com> writes:
On 07/09/2026 23:50, Janis Papanagnou wrote:
<snip>
It's even worse; given - as mentioned in another part of the thread -
that #includes are costly we often find some means to avoid not only
duplicated includes (by #ifndef LABEL, #define LABEL, ..., #endif)
in the header files but also to prevent accessing the header file in
the first place (by #ifndef LABEL, #include <label.h>, #endif). That
makes such C/C++ code rather messy, IMO. (And makes one appreciate
languages with an inherent good modularization method yet more.)
The duplication is a problem. If 50 modules each includes the header
files for a library such as SDL2, then a full build means a scanning the
headers 50 times, which means 4000 header files (80 unique) and 2.5M
lines of code (50K unique).
On a modern machine, this may add a few milliseconds to the build.
The operating systems, of course, would have the include files cached
in memory so there is no appreciable disk overhead caused by this
soi disant "duplication".
Of course, it is highly unlikely that a competent programmer would
include sdl header files in all fifty modules rather than
dedicating one module to handle all SDL wrappers.
What can be done to improve C#'s overall speed?
I've lost track of the hypothetical project organisation, and this is
not really the right place for a tutorial on the details of C++ modules.
˙However, I can point out one significant difference between C++
modules and, say, Python modules - in C++, the concept of "module" is independent of the concept of "namespace".˙ That means that the fully qualified names used by the importer of a module depends on the
namespaces used, not the module names.˙ (Of course in a well-organised project, there will be clear correlations between module names, file
names, and namespaces.˙ But they don't have to be one-to-one.)
I don't understand why it's okay to talk about C++ here but not C#?
C# is way better than C++.
The only reason people still use C++ is because of its overall speed
from what I can tell. Or else they haven't been cultured enough to
experience C# yet.
What can be done to improve C#'s overall speed?
Lane W <cactus_DAC@yahoo.com> writes:
The only reason people still use C++ is because of its overall speed
from what I can tell. Or else they haven't been cultured enough to
experience C# yet.
Imagine that you've posted in some forum that discusses C#.
I jump in to tell you that C++ is much better than C#, and I can't
understand why anyone would use C#, unless they're not cultured
enough to experience C++. That would be rude of me. The corollary
is left as an exercise.
Keith Thompson wrote:
Lane W <cactus_DAC@yahoo.com> writes:
The only reason people still use C++ is because of its overall speed
from what I can tell. Or else they haven't been cultured enough to
experience C# yet.
Imagine that you've posted in some forum that discusses C#.
I jump in to tell you that C++ is much better than C#, and I can't
understand why anyone would use C#, unless they're not cultured
enough to experience C++. That would be rude of me. The corollary
is left as an exercise.
I suppose I can understand that. Not only would it be rude of you, it
would also be false information, or perhaps a misled notion. No one
wants to be distributing false information on the Net.
I'm aware that you posted in response to a post that discussed C++,
one that I didn't complain about. That post was from a comp.lang.c
regular who makes plenty of relevant posts. A little topic drift
now and then is mostly harmless. I don't recall seeing *any*
relevant posts here from you.
Keith Thompson wrote:
I'm aware that you posted in response to a post that discussed C++,Well aren't you a fancy ancy.
one that I didn't complain about. That post was from a comp.lang.c
regular who makes plenty of relevant posts. A little topic drift
now and then is mostly harmless. I don't recall seeing *any*
relevant posts here from you.
I guess no one likes my switch solution to the poster fir's suggestion
for unwieldy if then else.
Now you are just being finicky. You and Janis are opposed to my switch formulation because it was me, yes me, Lane W. Janis just said he
didn't like it. You've gone so far as to say it was not relevant.
Talk about conceited posters.
Why don't you back up your finicky opinion with some facts. My post of
switch avoided the unwieldy braces and if then elses. All you have is
your green faces to show against it. That's not objective at all. I
deal in facts, not opinions.
Lane W <cactus_DAC@yahoo.com> writes:
Keith Thompson wrote:
I'm aware that you posted in response to a post that discussed C++,Well aren't you a fancy ancy.
one that I didn't complain about. That post was from a comp.lang.c
regular who makes plenty of relevant posts. A little topic drift
now and then is mostly harmless. I don't recall seeing *any*
relevant posts here from you.
I guess no one likes my switch solution to the poster fir's suggestion
for unwieldy if then else.
Now you are just being finicky. You and Janis are opposed to my switch
formulation because it was me, yes me, Lane W. Janis just said he
didn't like it. You've gone so far as to say it was not relevant.
Talk about conceited posters.
OK, let's talk about conceited posters.
I don't believe I've expressed an opinion on your "switch
formulation", whatever it was. You assume that I'm opposed to it
for personal reasons.
The fact is, I simply don't remember it. I probably glanced at
your post, but it didn't make much of an impression.
Keith Thompson wrote:
I'm aware that you posted in response to a post that discussed C++,Well aren't you a fancy ancy.
one that I didn't complain about.˙ That post was from a comp.lang.c
regular who makes plenty of relevant posts.˙ A little topic drift
now and then is mostly harmless.˙ I don't recall seeing *any*
relevant posts here from you.
I guess no one likes my switch solution to the poster fir's suggestion
for unwieldy if then else.
Now you are just being finicky. You and Janis are opposed to my switch formulation because it was me, yes me, Lane W. Janis just said he didn't like it. You've gone so far as to say it was not relevant.
Talk about conceited posters.
Why don't you back up your finicky opinion with some facts. My post of switch avoided the unwieldy braces and if then elses. All you have is
your green faces to show against it. That's not objective at all. I deal
in facts, not opinions.
On 08/09/2026 01:02, Waldek Hebisch wrote:
bart <bc@freeuk.com> wrote:
On 07/09/2026 14:33, David Brown wrote:
On 07/09/2026 14:55, bart wrote:
A typical module scheme works like this:
* You have, say, a project of 100 modules
* Each module selectively exports some entities
* Each module selectively imports some subset of the other 99 modules >>>>>
OK so far.
The result is that each module starts with some rag-tag collection of >>>>> 'import' statements, each different from any other module, and needing >>>>> a lot of maintenance.
No.˙ People who write /structured/ code do not do "rag-tag".
When a project is of a size where it is inconvenient to keep track of
all the separate "import" (or "#include", or whatever) statements, you >>>> use a hierarchy.˙ Instead of importing "dns", "udp", "http", etc.,
modules, you import "network".˙ The common "network" module pulls in the >>>> sub-modules.˙ You probably also organise things in directories and sub- >>>> directories, matching the module layout.˙ It is /structured/.
But it's a pattern I've seen a lot. In C also, as collections of
#includes; this example is from Lua, a project of only 35 modules, and
from one of its .c files:
#include "lprefix.h"
#include <float.h>
#include <limits.h>
#include <math.h>
#include <stdlib.h>
#include "lua.h"
#include "lcode.h"
#include "ldebug.h"
#include "ldo.h"
#include "lgc.h"
#include "llex.h"
#include "lmem.h"
#include "lobject.h"
#include "lopcodes.h"
#include "lparser.h"
#include "lstring.h"
#include "ltable.h"
#include "lvm.h"
Every file has a different set. In all, there are 28K lines of C code
among the .c files, and there are 466 #include lines. That is similar to >>> the maintenance nightmare where each file imports a particular set of
modules.
The organization looks sensible to me.
Not to me. This project uses these 35 files:
lapi.c lauxlib.c lbaselib.c lcode.c lcorolib.c lctype.c ldblib.c
ldebug.c ldo.c ldump.c lfunc.c lgc.c linit.c liolib.c llex.c
lmathlib.c lmem.c loadlib.c lobject.c lopcodes.c loslib.c lparser.c
lstate.c lstring.c lstrlib.c ltable.c ltablib.c ltests.c ltm.c lua.c lundump.c lutf8lib.c lvm.c lzio.c onelua.c
(A build will use 34 of them, depending whether it is EXE or DLL.)
With a module scheme, there should be no need for any additional info at all. But my point was, with how such schemes typically work, you still
have lots of mixed sets of 'import' statements at the start of each file.
Given that #include lines
are less than 2% of total and are likely to change very infrequently
I see no maintennce problem.
You can't quantify it like that. In any case, they will only change infrequently once you've finished development!
I found it annoying enough, and taking up enough time to devise a new
way of doing modules. And it is utter bliss.
But in this C project, there are also 28 .h files occupying 5Kloc. Much
of that is duplicating stuff that that is in a corresponding .c file.
There is also a makefile of 224 lines, but dense so about 0.8% of the
total .c and .h files.
However with a module scheme like mine and using the same file
structure, the project info needed occupies only 34 lines and 470 bytes.
There would be no header files, no developer makefiles (Lua uses a
separate installation makefile), and no hundreds of #includes.
However, if that bothers you, in
each file of your project you can put
#include "proj.h"
and put all needed includes in inside 'proj.h'. I you choose
good name you will never need to change it so maintenance cost
of '#include "proj.h"' will be close to 0. AFAICS maintenance
cost of 'proj.h' will be very similar to maintenance cost of
your module listing.
C gives you choice: you can have detailed control of what is
imported at cost of writing a lot of '#include' lines or you
can have common header which includes "everthing". With external
tools you can even automate maintanence of includes (say
automatially force any C file in a directory to include all
.h files in the same directory). You implemented a specific
way which you like. But if developers want something different
(as apparently Lua developers want) your compiler (if they
decide to use it) will force on them your way.
Yeah, external tools and workarounds. My first big project in C also
used a script to collate the local and exported functions.
Still, modern languages tend to have a module scheme, suggesting the 'flexible' C approach (I'd use the term 'prehistoric') wasn't quite enough.
Keith Thompson wrote:
Lane W <cactus_DAC@yahoo.com> writes:
Keith Thompson wrote:OK, let's talk about conceited posters.
I'm aware that you posted in response to a post that discussed C++,Well aren't you a fancy ancy.
one that I didn't complain about. That post was from a comp.lang.c
regular who makes plenty of relevant posts. A little topic drift
now and then is mostly harmless. I don't recall seeing *any*
relevant posts here from you.
I guess no one likes my switch solution to the poster fir's suggestion
for unwieldy if then else.
Now you are just being finicky. You and Janis are opposed to my switch
formulation because it was me, yes me, Lane W. Janis just said he
didn't like it. You've gone so far as to say it was not relevant.
Talk about conceited posters.
I don't believe I've expressed an opinion on your "switch
formulation", whatever it was. You assume that I'm opposed to it
for personal reasons.
The fact is, I simply don't remember it. I probably glanced at
your post, but it didn't make much of an impression.
It solved the poster's problem, but Janis didn't like it. He said it
made the programmer look in two different places. Even though the two
blocks were right next to each other. Why did you say you hadn't seen
any relevant posts if you weren't even reading the newsgroup?
What I'd do here is:
d=0
if (dodge<1)
d = 3
if (dodge<0.9)
d = 2
if (dodge<0.5)
d = 1
switch (d)
{
case 1:
slog("%s easily dodged attack...", being[k].name);
return 1;
case 2:
slog("%s hardly dodged attack...", being[k].name);
return 1;
case 3:
slog("%s dodged attack...", being[k].name);
return 1;
}
This is pretty easy to read but, it also shows that there are tens of millions of ways to do this.
[...]
I don't understand why it's okay to talk about C++ here but not C#? C#
is way better than C++.
The only reason people still use C++ is because of its overall speed
from what I can tell.
Or else they haven't been cultured enough to experience C# yet.
What can be done to improve C#'s overall speed?
Keith Thompson wrote:
Lane W <cactus_DAC@yahoo.com> writes:
The only reason people still use C++ is because of its overall speed
from what I can tell. Or else they haven't been cultured enough to
experience C# yet.
Imagine that you've posted in some forum that discusses C#.
I jump in to tell you that C++ is much better than C#, and I can't
understand why anyone would use C#, unless they're not cultured
enough to experience C++.˙ That would be rude of me.˙ The corollary
is left as an exercise.
I suppose I can understand that. Not only would it be rude of you, it
would also be false information, or perhaps a misled notion. No one
wants to be distributing false information on the Net.
Keith Thompson wrote:
[...][...]
[...] You and Janis are opposed to my switch
formulation because it was me, yes me, Lane W.
Janis just said he didn't
like it. You've gone so far as to say it was not relevant.
[...]
Lane W <cactus_DAC@yahoo.com> writes:
[128 lines deleted]
One of the things I avoid in C# is a nasty makefile, and generally
having to tool around in Unix. That is all taken care of by the C#
compiler included in the suite I use to generate my programs.
OK, I think we've established that you like C# better than C
(or C++).
This is comp.lang.c. Complaints about C are topical here, even
though some of the ones that introduced this thread are silly.
But if you want to discuss C#, please do so elsewhere.
On 08/09/2026 17:40, Scott Lurndal wrote:
bart <bc@freeuk.com> writes:
On 07/09/2026 23:50, Janis Papanagnou wrote:
It's even worse; given - as mentioned in another part of the thread -
that #includes are costly we often find some means to avoid not only
duplicated includes (by #ifndef LABEL, #define LABEL, ..., #endif)
in the header files but also to prevent accessing the header file in
the first place (by #ifndef LABEL, #include <label.h>, #endif). That
makes such C/C++ code rather messy, IMO. (And makes one appreciate
languages with an inherent good modularization method yet more.)
The duplication is a problem. If 50 modules each includes the header
files for a library such as SDL2, then a full build means a scanning the >>> headers 50 times, which means 4000 header files (80 unique) and 2.5M
lines of code (50K unique).
On a modern machine, this may add a few milliseconds to the build.
I don't think so. [...]
On 08/09/2026 00:50, Janis Papanagnou wrote:
It is almost universal practice to have such include guards in header
It's even worse; given - as mentioned in another part of the thread -
that #includes are costly we often find some means to avoid not only
duplicated includes (by #ifndef LABEL, #define LABEL, ..., #endif)
in the header files but also to prevent accessing the header file in
the first place (by #ifndef LABEL, #include <label.h>, #endif). That
makes such C/C++ code rather messy, IMO. (And makes one appreciate
languages with an inherent good modularization method yet more.)
files.
("#pragma once" is also often used, but while most compilers
support it, it is not standard and it can be problematic in some circumstances.)˙ The norm is to have the include guard cover everything except perhaps some comments at the head of the file, and compilers have fast paths to handle such discarded includes very efficiently.
So I would not count include guards as a problem in C - think of it more
as a quirky syntax for how header files are written.
Where other
languages might have "interface module XXX;", C has "#ifndef __XXX__".
Still, there can be problems when someone does not follow the common practice here.
It is also inconvenient when a programmer fails to include sub-includes
that are needed, so that the person using the header has to figure out a correct order and manually add any required include files.
C's include system is not hard to use well, but it is certainly possible
to use it badly and cause inconvenience to others.
On 08/09/2026 01:02, Waldek Hebisch wrote:
[...][...]
Still, modern languages tend to have a module scheme, suggesting the 'flexible' C approach (I'd use the term 'prehistoric') wasn't quite enough.
On 08/09/2026 17:40, Scott Lurndal wrote:
bart <bc@freeuk.com> writes:
On 07/09/2026 23:50, Janis Papanagnou wrote:
˙ <snip>
It's even worse; given - as mentioned in another part of the thread -
that #includes are costly we often find some means to avoid not only
duplicated includes (by #ifndef LABEL, #define LABEL, ..., #endif)
in the header files but also to prevent accessing the header file in
the first place (by #ifndef LABEL, #include <label.h>, #endif). That
makes such C/C++ code rather messy, IMO. (And makes one appreciate
languages with an inherent good modularization method yet more.)
The duplication is a problem. If 50 modules each includes the header
files for a library such as SDL2, then a full build means a scanning the >>> headers 50 times, which means 4000 header files (80 unique) and 2.5M
lines of code (50K unique).
On a modern machine, this may add a few milliseconds to the build.
I don't think so. Here is a one-file test C program:
˙˙ '#include <SDL3/SDL.h>'
This is a test that compiles 50 copies of it:
˙˙ c:\sdl>tm gcc -c -I. s*.c
˙˙ TM: 36.59
That's 36,000 milliseconds, rather more than a few. (SDL3 is not 80Kloc rather than 50Kloc.)
If I use a precompiled header, then it reduces to 5000 milliseconds.
However that header is 30MB, 8 times the size of the headers.
(I believe that SDL3 uses windows.h, another huge set of headers. Using
TCC here takes 1.5 seconds without using precompiled headers, but TCC
uses a compact version of windows.h.)
On 08/09/2026 7:52 AM, Keith Thompson wrote:
Lane W <cactus_DAC@yahoo.com> writes:
[128 lines deleted]
One of the things I avoid in C# is a nasty makefile, and generally
having to tool around in Unix. That is all taken care of by the C#
compiler included in the suite I use to generate my programs.
OK, I think we've established that you like C# better than C
(or C++).
This is comp.lang.c.˙ Complaints about C are topical here, even
though some of the ones that introduced this thread are silly.
But if you want to discuss C#, please do so elsewhere.
Oh, don't mind Keith.˙ He likes to butt in on other people's discussions
and behave like he's some owner of comp.lang.c.˙ He's not.˙ There isn't
even a comp.lang.csharp group to direct people towards.˙ I guess Keith
will just have to start a discussion in news.groups.proposals about it.
I've added microsoft.public.dotnet.csharp.general to this discussion,
but I have no idea if Eternal September subscribes to it, which I be-
lieve is what most techies use to access usenet.˙ And the last on-topic
post in microsoft.public.dotnet.csharp.general seems to have been six-
teen years ago.
That's a long time for nobody to get comp.lang.csharp running.
So please feel free to complain in comp.lang.c -- and let the # be si-
lent -- until someone gets irritated enough to make a proposal that
sticks!
Best wishes, and happy coding in C#!
[...]
Module system has other advantages over C. First, in C sane
developers use headers in consistent way, but language
does not enforce it. Typical module system enforces
consistency. Second, module interfaces can be parsed once,
avoiding problem of repeated re-parsing of C headers.
Third, modules resolve name clashes: the "same" name in
two different modules is disambiguated by its source module.
Fourth, given a main module compiler can track its imports
and build the program without need for separate Makefile.
[...]
On 2026-09-08 09:25, David Brown wrote:
On 08/09/2026 00:50, Janis Papanagnou wrote:
It is almost universal practice to have such include guards in header
It's even worse; given - as mentioned in another part of the thread -
that #includes are costly we often find some means to avoid not only
duplicated includes (by #ifndef LABEL, #define LABEL, ..., #endif)
in the header files but also to prevent accessing the header file in
the first place (by #ifndef LABEL, #include <label.h>, #endif). That
makes such C/C++ code rather messy, IMO. (And makes one appreciate
languages with an inherent good modularization method yet more.)
files.
Yeah, that was also my suspicion. (Though I'm not any more practically involved in professional C/C++ development so I'm not really up to date
what additional options we nowadays have.)
("#pragma once" is also often used, but while most compilers support
it, it is not standard and it can be problematic in some
circumstances.)˙ The norm is to have the include guard cover
everything except perhaps some comments at the head of the file, and
compilers have fast paths to handle such discarded includes very
efficiently.
So I would not count include guards as a problem in C - think of it
more as a quirky syntax for how header files are written.
Well, I wouldn't actually call it a "problem". - I mean, it's "C" we're talking about. :-)
Yes, the syntax (and all the overhead) is what I find annoying. (But
I'm used to it, and it's also not worth complaining. It's effective.)
Where other languages might have "interface module XXX;", C has
"#ifndef __XXX__".
I'm not feeling competent enough concerning "the best" module interface methods and their discussion, but I've met a handful languages/methods
during my IT life and the C/C++ "model" is rather at the low end. (But
I've also programmed in languages that didn't have any module-concept
at all. - We've to use what we are supposed to work with.)
Still, there can be problems when someone does not follow the common
practice here.
We defined our company (coding-)standards to cover that. (And had our technical mechanisms to alleviate the burden of the textual overhead.)
It is also inconvenient when a programmer fails to include sub-
includes that are needed, so that the person using the header has to
figure out a correct order and manually add any required include files.
Hmm.. - I'm not sure I can follow you here. - If some of our headers
had its own dependencies it was the responsibility of that header to
satisfy them. - I recall there were occasionally issues with lacking consistency, but that was in our project contexts considered a bug.
C's include system is not hard to use well, but it is certainly
possible to use it badly and cause inconvenience to others.
Yes. It's primitive. It does its job. And you should accompany their
use by standards and conventions.
On 2026-09-08 13:47, bart wrote:
On 08/09/2026 01:02, Waldek Hebisch wrote:
[...][...]
Still, modern languages tend to have a module scheme, suggesting the
'flexible' C approach (I'd use the term 'prehistoric') wasn't quite
enough.
A necessary consequence of the growing systems and software
architectures. But even some legacy languages had already
modularization concepts back then! So it's not an excuse to
provide only a primitive #include mechanism. But I wouldn't
be so critical given the time when "C" had been designed.
You should take into account C's design-principles and also
when it came out and sort them in, in comparison to other
language schools; compare (for example) the release dates
of Pascal -> Modula (and what these two provided here).
On 09/09/2026 09:59, Janis Papanagnou wrote:
We defined our company (coding-)standards to cover that. (And had our
technical mechanisms to alleviate the burden of the textual overhead.)
Most serious developers use some kind of IDE or advanced editor, and
most such tools can generate include guards automatically when you
create a new header file.
[...]
I follow that principle too.˙ But not everyone does.˙ So I would have :
#ifndef __NUMBER_GENERATOR_H__
#define __NUMBER_GENERATOR_H__ 1
[...]
On 09/09/2026 10:13, Janis Papanagnou wrote:
On 2026-09-08 13:47, bart wrote:
On 08/09/2026 01:02, Waldek Hebisch wrote:
[...][...]
Still, modern languages tend to have a module scheme, suggesting the
'flexible' C approach (I'd use the term 'prehistoric') wasn't quite
enough.
A necessary consequence of the growing systems and software
architectures. But even some legacy languages had already
modularization concepts back then! So it's not an excuse to
provide only a primitive #include mechanism. But I wouldn't
be so critical given the time when "C" had been designed.
You should take into account C's design-principles and also
when it came out and sort them in, in comparison to other
language schools; compare (for example) the release dates
of Pascal -> Modula (and what these two provided here).
AFAIK, Pascal originally did not have any kind of "unit" system (its
module equivalent) - you used textual inclusion files.˙ But you then compiled everything as one big Pascal file rather than having separate compilation.˙ (This may have varied between Pascal implementations.)
On 09/09/2026 09:59, Janis Papanagnou wrote:[...]
Hmm.. - I'm not sure I can follow you here. - If some of our headers
had its own dependencies it was the responsibility of that header to
satisfy them. - I recall there were occasionally issues with lacking
consistency, but that was in our project contexts considered a bug.
I follow that principle too. But not everyone does. So I would have :
#ifndef __NUMBER_GENERATOR_H__
#define __NUMBER_GENERATOR_H__ 1
#include <stdint.h>
extern uint64_t make_a_big_number(void);
#endif // #ifndef __NUMBER_GENERATOR_H__
But some people would omit the "#include <stdint.h>" line, and leave
that as the responsibility of the person writing the C file. The same applies to dependencies on local header files.
On 2026-09-09 10:38, David Brown wrote:
On 09/09/2026 10:13, Janis Papanagnou wrote:
On 2026-09-08 13:47, bart wrote:
On 08/09/2026 01:02, Waldek Hebisch wrote:
[...][...]
Still, modern languages tend to have a module scheme, suggesting the
'flexible' C approach (I'd use the term 'prehistoric') wasn't quite
enough.
A necessary consequence of the growing systems and software
architectures. But even some legacy languages had already
modularization concepts back then! So it's not an excuse to
provide only a primitive #include mechanism. But I wouldn't
be so critical given the time when "C" had been designed.
You should take into account C's design-principles and also
when it came out and sort them in, in comparison to other
language schools; compare (for example) the release dates
of Pascal -> Modula (and what these two provided here).
AFAIK, Pascal originally did not have any kind of "unit" system (its
module equivalent) - you used textual inclusion files.˙ But you then
compiled everything as one big Pascal file rather than having separate
compilation.˙ (This may have varied between Pascal implementations.)
Yes, exactly. - Original Pascal didn't have anything, then came "C"
timely - providing something that Pascal didn't have! - and Wirth's
next language Modula then had a concept.
Sorry if I was unclear.
Janis
On 08/09/2026 21:08, bart wrote:
On 08/09/2026 17:40, Scott Lurndal wrote:
bart <bc@freeuk.com> writes:
On 07/09/2026 23:50, Janis Papanagnou wrote:
˙ <snip>
It's even worse; given - as mentioned in another part of the thread - >>>>> that #includes are costly we often find some means to avoid not only >>>>> duplicated includes (by #ifndef LABEL, #define LABEL, ..., #endif)
in the header files but also to prevent accessing the header file in >>>>> the first place (by #ifndef LABEL, #include <label.h>, #endif). That >>>>> makes such C/C++ code rather messy, IMO. (And makes one appreciate
languages with an inherent good modularization method yet more.)
The duplication is a problem. If 50 modules each includes the header
files for a library such as SDL2, then a full build means a scanning
the
headers 50 times, which means 4000 header files (80 unique) and 2.5M
lines of code (50K unique).
On a modern machine, this may add a few milliseconds to the build.
I don't think so. Here is a one-file test C program:
˙˙˙ '#include <SDL3/SDL.h>'
This is a test that compiles 50 copies of it:
˙˙˙ c:\sdl>tm gcc -c -I. s*.c
˙˙˙ TM: 36.59
That's 36,000 milliseconds, rather more than a few. (SDL3 is not
80Kloc rather than 50Kloc.)
If I use a precompiled header, then it reduces to 5000 milliseconds.
However that header is 30MB, 8 times the size of the headers.
(I believe that SDL3 uses windows.h, another huge set of headers.
Using TCC here takes 1.5 seconds without using precompiled headers,
but TCC uses a compact version of windows.h.)
Without having used SDL, or done any comparisons or measurements, I
think there are a few things worth considering here.˙ I am not
commenting directly on your particular setup.
1. SDL headers are /big/, because the library is big.˙ Programs that use
SDL general involve a lot of files and a lot of code.˙ So compilation of
SDL programs is naturally going to be more demanding than compilation of "hello world" programs - the time taken to "digest" the headers is then
a smaller proportion of the compilation compared to analysing and
optimising the user code.
I see my current project taking perhaps an order of magnitude longer to build on Windows systems than Linux, with similar processors (I do have
more ram in my system, but I don't think that's critical).
˙ Trying to optimise or flatten header sets
for some library would be a waste of effort - the effect is too minor.
Of course, for someone writing and distributing a popular library, it
might be worth making flattened versions of their headers available as
even a small effect is multiplied by the number of people using the
library.
I did a brief check of the most include-heavy file in my currentYes, these are all techniques that can be used to mitigate what remains,
project.˙ There are about 160 include files going into the compile, with about 200 include directives executed (some headers presumably have
include directives before their include guard).˙ Total pre-processed
code is 3.6 million lines, of which 400 are from the actual C++ file. Pre-processing takes 0.1 seconds, with the full optimised compile taking 0.55 seconds.
"Touching" that one file, and doing "make -j" takes 1.3 seconds - it includes linking after the compiler.˙ A full clean "make -j 18" rebuild takes 6.4 seconds in parallel.˙ A non-parallel build takes 63 seconds.
During typical development, I rebuild after changing a file.˙ 1.3
seconds is close enough to "instant" that it is not an issue - I make changes, press ctrl-S then ctrl-B, and the error markers are in the IDE after 0.5 seconds (there's no linking when I have compile-time errors in
the code!).˙ Saving a hypothetical maximum of 0.1 seconds from flattened headers would make no difference.
But using parallel builds controlled by make, rather than serial builds, cuts the full build time by 90%.˙ (Sometimes a header change triggers a re-compile of large parts of the code base.)˙ Using make to handle dependencies and compile only when needed saves 98% of the time compared
to full serial builds.
Of course it would be nice to shave off another 10% from faster header handling - but it's a drop in the ocean compared to the other generic techniques I already use.
Johann 'Myrkraverk' Oskarsson pisze:Yeah, I don't worry about Keith and trolls like him, and discuss what I
On 08/09/2026 7:52 AM, Keith Thompson wrote:
Lane W <cactus_DAC@yahoo.com> writes:
[128 lines deleted]
One of the things I avoid in C# is a nasty makefile, and generally
having to tool around in Unix. That is all taken care of by the C#
compiler included in the suite I use to generate my programs.
OK, I think we've established that you like C# better than C
(or C++).
This is comp.lang.c.˙ Complaints about C are topical here, even
though some of the ones that introduced this thread are silly.
But if you want to discuss C#, please do so elsewhere.
Oh, don't mind Keith.˙ He likes to butt in on other people's discussions
and behave like he's some owner of comp.lang.c.˙ He's not.˙ There isn't
even a comp.lang.csharp group to direct people towards.˙ I guess Keith
will just have to start a discussion in news.groups.proposals about it.
I've added microsoft.public.dotnet.csharp.general to this discussion,
but I have no idea if Eternal September subscribes to it, which I be-
lieve is what most techies use to access usenet.˙ And the last on-topic
post in microsoft.public.dotnet.csharp.general seems to have been six-
teen years ago.
That's a long time for nobody to get comp.lang.csharp running.
So please feel free to complain in comp.lang.c -- and let the # be si-
lent -- until someone gets irritated enough to make a proposal that
sticks!
Best wishes, and happy coding in C#!
this is probably not god taking on this ...the offtopics imo depending
on amount (yet quality)..if group has some focus it should be focus on
c realted things with some offtopics possible not focus on c not realted offtopics with slight amount of c related...
so i find some sense in what keith t says though i personally cant agree
with his inner idea this group is only for discussing
1) c standards
not
2) c ideas
or
3) c programming
On 09/09/2026 09:18, David Brown wrote:
On 08/09/2026 21:08, bart wrote:
On 08/09/2026 17:40, Scott Lurndal wrote:
bart <bc@freeuk.com> writes:
On 07/09/2026 23:50, Janis Papanagnou wrote:
˙ <snip>
The duplication is a problem. If 50 modules each includes the header >>>>> files for a library such as SDL2, then a full build means a
scanning the
headers 50 times, which means 4000 header files (80 unique) and 2.5M >>>>> lines of code (50K unique).
On a modern machine, this may add a few milliseconds to the build.
I don't think so. Here is a one-file test C program:
˙˙˙ '#include <SDL3/SDL.h>'
This is a test that compiles 50 copies of it:
˙˙˙ c:\sdl>tm gcc -c -I. s*.c
˙˙˙ TM: 36.59
That's 36,000 milliseconds, rather more than a few. (SDL3 is not
80Kloc rather than 50Kloc.)
I tried my SDL3 test with WSL and Windows:
WSL˙˙˙˙˙˙ 22.5 seconds˙ (real)
Windows˙˙ 38˙˙ seconds˙ (elapsed)
This is that amount of files/includes described above, times 50. Tests
were done twice and this is the faster of the two. (Yesterday the
Windows one was 36; timings vary.)
However, this doesn't tell me much about whether building on Windows is inherently slower, since SDL for Windows uses 'windows.h', while for
Linux it may use X11 or whatever. Maybe the former is much larger.
It's possible that your magnitude difference is because you need
windows.h or some other MS header that will be more bloated than the equivalent POSIX.
Or maybe WSL is still really Windows (but I haven't seen a spectacular difference when I used a true Linux).
˙ Trying to optimise or flatten header sets for some library would be
a waste of effort - the effect is too minor.
If that was routinely done, then perhaps we wouldn't need all those
extra resources, tools, and workarounds!
On 09/09/2026 4:18 PM, fir wrote:
Johann 'Myrkraverk' Oskarsson pisze:Yeah, I don't worry about Keith and trolls like him, and discuss what I
On 08/09/2026 7:52 AM, Keith Thompson wrote:
Lane W <cactus_DAC@yahoo.com> writes:
[128 lines deleted]
One of the things I avoid in C# is a nasty makefile, and generally
having to tool around in Unix. That is all taken care of by the C#
compiler included in the suite I use to generate my programs.
OK, I think we've established that you like C# better than C
(or C++).
This is comp.lang.c.˙ Complaints about C are topical here, even
though some of the ones that introduced this thread are silly.
But if you want to discuss C#, please do so elsewhere.
Oh, don't mind Keith.˙ He likes to butt in on other people's discussions >>> and behave like he's some owner of comp.lang.c.˙ He's not.˙ There isn't
even a comp.lang.csharp group to direct people towards.˙ I guess Keith
will just have to start a discussion in news.groups.proposals about it.
I've added microsoft.public.dotnet.csharp.general to this discussion,
but I have no idea if Eternal September subscribes to it, which I be-
lieve is what most techies use to access usenet.˙ And the last on-topic
post in microsoft.public.dotnet.csharp.general seems to have been six-
teen years ago.
That's a long time for nobody to get comp.lang.csharp running.
So please feel free to complain in comp.lang.c -- and let the # be si-
lent -- until someone gets irritated enough to make a proposal that
sticks!
Best wishes, and happy coding in C#!
this is probably not god taking on this ...the offtopics imo depending
on amount (yet quality)..if group has some focus it should be focus on
c realted things with some offtopics possible not focus on c not realted
offtopics with slight amount of c related...
so i find some sense in what keith t says though i personally cant agree
with his inner idea this group is only for discussing
1) c standards
not
2) c ideas
or
3) c programming
want in comp.lang.c.˙ Including meta discussions like this one, about
what should and shouldn't be discussed in comp.lang.c.
Plus, it's fairly clear none of the usual trolls code anything in C, as
I demonstrated when I gave you some book recommendations.
Best wishes, and happy C coding!
Johann 'Myrkraverk' Oskarsson pisze:
On 09/09/2026 4:18 PM, fir wrote:
Johann 'Myrkraverk' Oskarsson pisze:Yeah, I don't worry about Keith and trolls like him, and discuss what I
On 08/09/2026 7:52 AM, Keith Thompson wrote:
Lane W <cactus_DAC@yahoo.com> writes:
[128 lines deleted]
One of the things I avoid in C# is a nasty makefile, and generally >>>>>> having to tool around in Unix. That is all taken care of by the C# >>>>>> compiler included in the suite I use to generate my programs.
OK, I think we've established that you like C# better than C
(or C++).
This is comp.lang.c.˙ Complaints about C are topical here, even
though some of the ones that introduced this thread are silly.
But if you want to discuss C#, please do so elsewhere.
Oh, don't mind Keith.˙ He likes to butt in on other people's
discussions
and behave like he's some owner of comp.lang.c.˙ He's not.˙ There isn't >>>> even a comp.lang.csharp group to direct people towards.˙ I guess Keith >>>> will just have to start a discussion in news.groups.proposals about it. >>>>
I've added microsoft.public.dotnet.csharp.general to this discussion,
but I have no idea if Eternal September subscribes to it, which I be-
lieve is what most techies use to access usenet.˙ And the last on-topic >>>> post in microsoft.public.dotnet.csharp.general seems to have been six- >>>> teen years ago.
That's a long time for nobody to get comp.lang.csharp running.
So please feel free to complain in comp.lang.c -- and let the # be si- >>>> lent -- until someone gets irritated enough to make a proposal that
sticks!
Best wishes, and happy coding in C#!
this is probably not god taking on this ...the offtopics imo
depending on amount (yet quality)..if group has some focus it should
be focus on
c realted things with some offtopics possible not focus on c not realted >>> offtopics with slight amount of c related...
so i find some sense in what keith t says though i personally cant agree >>> with his inner idea this group is only for discussing
1) c standards
not
2) c ideas
or
3) c programming
want in comp.lang.c.˙ Including meta discussions like this one, about
what should and shouldn't be discussed in comp.lang.c.
Plus, it's fairly clear none of the usual trolls code anything in C, as
I demonstrated when I gave you some book recommendations.
Best wishes, and happy C coding!
keith probably used to call me a troll (oz i not stick to his own rigid rules)
so i could eventuall call him back a troll but as i once said if i noticed
it is better to value regular users of this group becouse if not hem
the group culd not exist and i would have no place to talk at all
so i dont call him a troll, becouse he is okay user overally i just
disagree in some things
On 2026-09-09 10:35, David Brown wrote:
On 09/09/2026 09:59, Janis Papanagnou wrote:
We defined our company (coding-)standards to cover that. (And had our
technical mechanisms to alleviate the burden of the textual overhead.)
Most serious developers use some kind of IDE or advanced editor, and
most such tools can generate include guards automatically when you
create a new header file.
Yes, that was what I've meant and what we've done. In addition we
provided templates, and there were external (non-editor-dependent)
generators to quickly create source frames for .h and .cc files;
specifically for C++ that was very useful and saved a lot of time
since we also generated standard class contents, standard headers,
comment frames, c'tors, d'tors, copy-c'tors, =ops, and maybe some
more things.
[...]
I follow that principle too.˙ But not everyone does.˙ So I would have :
#ifndef __NUMBER_GENERATOR_H__
#define __NUMBER_GENERATOR_H__ 1
BTW, since I'm seeing that...
I recall we've had defined these without value assignment just as
˙ #define __NUMBER_GENERATOR_H__
and I seem to recall we've determined that this would suffice and
verified to create no problems. - Is that still valid? (And if so,
what's the purpose of the value then?)
Janis
Keith Thompson wrote:
Imagine that you've posted in some forum that discusses C#.
I jump in to tell you that C++ is much better than C#, and I can't
understand why anyone would use C#, unless they're not cultured
enough to experience C++. That would be rude of me. The corollary
is left as an exercise.
I suppose I can understand that. Not only would it be rude of you, it
would also be false information, or perhaps a misled notion. No one
wants to be distributing false information on the Net.
David Brown <david.brown@hesbynett.no> writes:
On 09/09/2026 09:59, Janis Papanagnou wrote:[...]
Hmm.. - I'm not sure I can follow you here. - If some of our headers
had its own dependencies it was the responsibility of that header to
satisfy them. - I recall there were occasionally issues with lacking
consistency, but that was in our project contexts considered a bug.
I follow that principle too. But not everyone does. So I would have :
#ifndef __NUMBER_GENERATOR_H__
#define __NUMBER_GENERATOR_H__ 1
#include <stdint.h>
extern uint64_t make_a_big_number(void);
#endif // #ifndef __NUMBER_GENERATOR_H__
A couple of nitpicks:
I'd choose a non-reserved name for the macro, probably
H_NUMBER_GENERATOR (not NUMBER_GENERATOR_H because that produces a
reserved name for a header whose name starts with 'e'). Admittedly
the odds of a collision with an implementation-defined reserved
name are small, but I prefer to make them zero. I'd also use
`#define ...` rather than `#define ... 1`; it only matters whether
it's defined or not, not what it expands to.
But some people would omit the "#include <stdint.h>" line, and leave
that as the responsibility of the person writing the C file. The same
applies to dependencies on local header files.
Ick. That would mean that if a future version depends on another
standard header, all client code has to be updated, even if it
doesn't use the new functionality.
On 09/09/2026 11:45, Keith Thompson wrote:
David Brown <david.brown@hesbynett.no> writes:
On 09/09/2026 09:59, Janis Papanagnou wrote:[...]
Hmm.. - I'm not sure I can follow you here. - If some of our headers
had its own dependencies it was the responsibility of that header to
satisfy them. - I recall there were occasionally issues with lacking
consistency, but that was in our project contexts considered a bug.
I follow that principle too.˙ But not everyone does.˙ So I would have :
#ifndef __NUMBER_GENERATOR_H__
#define __NUMBER_GENERATOR_H__ 1
#include <stdint.h>
extern uint64_t make_a_big_number(void);
#endif˙˙˙ // #ifndef __NUMBER_GENERATOR_H__
A couple of nitpicks:
I'd choose a non-reserved name for the macro, probably
H_NUMBER_GENERATOR (not NUMBER_GENERATOR_H because that produces a
reserved name for a header whose name starts with 'e').˙ Admittedly
the odds of a collision with an implementation-defined reserved
name are small, but I prefer to make them zero.˙ I'd also use
`#define ...` rather than `#define ... 1`; it only matters whether
it's defined or not, not what it expands to.
Sure.˙ In practice, it's common to include a bit of directory structure
in the header guard name too.
But some people would omit the "#include <stdint.h>" line, and leave
that as the responsibility of the person writing the C file.˙ The same
applies to dependencies on local header files.
Ick.˙ That would mean that if a future version depends on another
standard header, all client code has to be updated, even if it
doesn't use the new functionality.
Yes.
I've seen worse issues than that, however.
Imagine a library where there is a configuration option NUMBER_OF_THINGS that library users might want to specify, or might want to leave as the default.
So you have :
// user_config.h
#define NUMBER_OF_THINGS 20
// platform_default.h
#ifndef NUMBER_OF_THINGS
#define NUMBER_OF_THINGS 30˙˙˙ // Standard on target X
#endif
// library_funcs.h
#ifndef NUMBER_OF_THINGS
#define NUMBER_OF_THINGS 40˙˙˙ // Default if not overridden
#endif
struct Thing_Holder {
˙˙˙˙int things[NUMBER_OF_THINGS];
};
extern void do_things(struct Thing_Holder * th);
// library_funcs.c
#include "user_config.h"˙˙˙ // User overrides
#include "platform_default.h"˙˙˙ // Platform-specific details
#include "library_funcs.h"
void do_things(struct Thing_Holder * th) {
˙˙˙˙...
}
And then your own code has:
#include "library_funcs.h"
#include "user_config.h"
Imagine the hilarity that results when trying to debug the code.˙ And
then suppose that there's another similar pre-processor symbol that
someone has added manually to an IDE project setup (giving a "-DNUMBER_OF_OTHER_THINGS=42" command-line argument to the compiler),
but that's missing when the project is moved over to a different IDE by someone who didn't know about it.
This kind of nonsense turns up regularly in embedded programming for libraries for RTOS's, network stacks, and manufacturer-provided SDKs and other stuff.˙ Oh, and you might also find multiple different files named "user_config.h" in example code from the supplier, with different
settings (and no information about /why/ particular settings are
picked).˙ Every little bit of the SDK is then in its own directory of
two or three files, and each of these directories is added to the
include path for the compilation, in a random and sometimes inconsistent order.
C's include system works well when used in a sensible and disciplined manner, but unfortunately not all C programmers are sensible and disciplined.
David Brown wrote:
C's include system works well when used in a sensible and disciplinedAgreed. Plus some C programmers use the switch keyword, which we all
manner, but unfortunately not all C programmers are sensible and
disciplined.
agree is BAD BAD BAD, right Janis and Keith?
In fact at work, I'm regularly known as __The Evil One__ because of my propensity to use the switch construct.
Every company brochure shows my position as Sauron in the company
fables, with my signature golden ring. Pure evil, I guarantee it.
fir pisze:
Johann 'Myrkraverk' Oskarsson pisze:besides he is partally right - he has a bit rigid definitions who troll
On 09/09/2026 4:18 PM, fir wrote:
Johann 'Myrkraverk' Oskarsson pisze:Yeah, I don't worry about Keith and trolls like him, and discuss what I
On 08/09/2026 7:52 AM, Keith Thompson wrote:
Lane W <cactus_DAC@yahoo.com> writes:
[128 lines deleted]
One of the things I avoid in C# is a nasty makefile, and generally >>>>>>> having to tool around in Unix. That is all taken care of by the C# >>>>>>> compiler included in the suite I use to generate my programs.
OK, I think we've established that you like C# better than C
(or C++).
This is comp.lang.c.˙ Complaints about C are topical here, even
though some of the ones that introduced this thread are silly.
But if you want to discuss C#, please do so elsewhere.
Oh, don't mind Keith.˙ He likes to butt in on other people's
discussions
and behave like he's some owner of comp.lang.c.˙ He's not.˙ There
isn't
even a comp.lang.csharp group to direct people towards.˙ I guess Keith >>>>> will just have to start a discussion in news.groups.proposals about >>>>> it.
I've added microsoft.public.dotnet.csharp.general to this discussion, >>>>> but I have no idea if Eternal September subscribes to it, which I be- >>>>> lieve is what most techies use to access usenet.˙ And the last on-
topic
post in microsoft.public.dotnet.csharp.general seems to have been six- >>>>> teen years ago.
That's a long time for nobody to get comp.lang.csharp running.
So please feel free to complain in comp.lang.c -- and let the # be si- >>>>> lent -- until someone gets irritated enough to make a proposal that
sticks!
Best wishes, and happy coding in C#!
this is probably not god taking on this ...the offtopics imo
depending on amount (yet quality)..if group has some focus it should
be focus on
c realted things with some offtopics possible not focus on c not
realted
offtopics with slight amount of c related...
so i find some sense in what keith t says though i personally cant
agree
with his inner idea this group is only for discussing
1) c standards
not
2) c ideas
or
3) c programming
want in comp.lang.c.˙ Including meta discussions like this one, about
what should and shouldn't be discussed in comp.lang.c.
Plus, it's fairly clear none of the usual trolls code anything in C, as
I demonstrated when I gave you some book recommendations.
Best wishes, and happy C coding!
keith probably used to call me a troll (oz i not stick to his own
rigid rules)
so i could eventuall call him back a troll but as i once said if i
noticed
it is better to value regular users of this group becouse if not hem
the group culd not exist and i would have no place to talk at all
so i dont call him a troll, becouse he is okay user overally i just
disagree in some things
is - but this is kinda complex matter becouse depending on definitions i
may be a troll according to one, he may be atroll according to another
and so on..and which definitions are good and for what reason is a
complex thing - not sure if this is resolvable...
generally i find whats good to improve some focus and knowledge here as
godo and whats the oposite makin brainless spam is bad etc
On 2026-09-09 02:47, Lane W wrote:
Keith Thompson wrote:
[...][...]
[...] You and Janis are opposed to my switch formulation because it
was me, yes me, Lane W.
How cocky (and completely wrong) to believe that my criticism of your 'if'/'switch' code was a personal thing; the keywords I provided as
hints should have made that very clear that it was really bad code;
and not only "bad" code.
(But now I see that there's indeed something evolving that is related
to your personality, but also to the quality of your posts' contents.
So I'll abstain from further seeing your contributions here. *p*)
I think it's okay if there's an argumentative relation or comparisonJanis just said he didn't like it. You've gone so far as to say it was
not relevant.
The only reason people still use C++ is because of its overall speed from what I can tell.
Or else they haven't been cultured enough to experience C# yet.
What can be done to improve C#'s overall speed?
On 09/09/2026 15:14, Lane W wrote:
David Brown wrote:
C's include system works well when used in a sensible and disciplinedAgreed. Plus some C programmers use the switch keyword, which we all
manner, but unfortunately not all C programmers are sensible and
disciplined.
agree is BAD BAD BAD, right Janis and Keith?
In fact at work, I'm regularly known as __The Evil One__ because of my
propensity to use the switch construct.
Every company brochure shows my position as Sauron in the company
fables, with my signature golden ring. Pure evil, I guarantee it.
I can't understand where this martyr complex comes from.˙ I saw your
post about an alternative way to structure fir's code, and I thought it
was a poor solution.˙ That was not because it used "switch", or because /you/ wrote it, but simply because I did not think it was a clear or maintainable way to express the algorithm.˙ It added complexity and a
layer of indirection without adding advantages of flexibility or
clarity.˙ (I fully agree with your comment in the post that there are
many ways to structure the code here - without knowing much more about
the program, it is impossible to give a good comparison to them.)
If you don't want people to express opinions on code snippets or suggestions, don't post them.˙ I think most regulars here (and certainly Janis and Keith) will judge them as fairly as they can, on the merits of
the code - with a total disregard to who posts them.˙ (The exception is
that many regulars have kill-filed some of the more irksome posters.)
Don't imagine that people will treat your posts or code samples
specially.˙ You are not that important, and you haven't been posting in c.l.c. long enough to have established much of a reputation (positive or negative).
It would be a lot better if you stuck to writing posts that are sensible replies within threads, or start new topical threads.˙ Post C code, get feedback on it, and treat that feedback as constructive criticism of the code - not as some kind of personal attack.˙ (My post here is intended
as constructive criticism - it is not a personal attack.)
David Brown wrote:
On 09/09/2026 15:14, Lane W wrote:It's˙ because many of the lot of you are tying your hands with what you think Policy tells you. The poster asked how to avoid if then else and I showed him a way. It solved his problem. Where is the evil in that? Who
David Brown wrote:
C's include system works well when used in a sensible andAgreed. Plus some C programmers use the switch keyword, which we all
disciplined manner, but unfortunately not all C programmers are
sensible and disciplined.
agree is BAD BAD BAD, right Janis and Keith?
In fact at work, I'm regularly known as __The Evil One__ because of
my propensity to use the switch construct.
Every company brochure shows my position as Sauron in the company
fables, with my signature golden ring. Pure evil, I guarantee it.
I can't understand where this martyr complex comes from.˙ I saw your
post about an alternative way to structure fir's code, and I thought
it was a poor solution.˙ That was not because it used "switch", or
because /you/ wrote it, but simply because I did not think it was a
clear or maintainable way to express the algorithm.˙ It added
complexity and a layer of indirection without adding advantages of
flexibility or clarity.˙ (I fully agree with your comment in the post
that there are many ways to structure the code here - without knowing
much more about the program, it is impossible to give a good
comparison to them.)
If you don't want people to express opinions on code snippets or
suggestions, don't post them.˙ I think most regulars here (and
certainly Janis and Keith) will judge them as fairly as they can, on
the merits of the code - with a total disregard to who posts them.
(The exception is that many regulars have kill-filed some of the more
irksome posters.)
Don't imagine that people will treat your posts or code samples
specially.˙ You are not that important, and you haven't been posting
in c.l.c. long enough to have established much of a reputation
(positive or negative).
It would be a lot better if you stuck to writing posts that are
sensible replies within threads, or start new topical threads.˙ Post C
code, get feedback on it, and treat that feedback as constructive
criticism of the code - not as some kind of personal attack.˙ (My post
here is intended as constructive criticism - it is not a personal
attack.)
is this deity you worship that say to you you can gauge a morality of a snippet of code based on your pathetic standards and policies at YOUR company?
Lane W pisze:
David Brown wrote:
On 09/09/2026 15:14, Lane W wrote:It's˙ because many of the lot of you are tying your hands with what
David Brown wrote:
C's include system works well when used in a sensible andAgreed. Plus some C programmers use the switch keyword, which we all
disciplined manner, but unfortunately not all C programmers are
sensible and disciplined.
agree is BAD BAD BAD, right Janis and Keith?
In fact at work, I'm regularly known as __The Evil One__ because of
my propensity to use the switch construct.
Every company brochure shows my position as Sauron in the company
fables, with my signature golden ring. Pure evil, I guarantee it.
I can't understand where this martyr complex comes from.˙ I saw your
post about an alternative way to structure fir's code, and I thought
it was a poor solution.˙ That was not because it used "switch", or
because /you/ wrote it, but simply because I did not think it was a
clear or maintainable way to express the algorithm.˙ It added
complexity and a layer of indirection without adding advantages of
flexibility or clarity.˙ (I fully agree with your comment in the post
that there are many ways to structure the code here - without knowing
much more about the program, it is impossible to give a good
comparison to them.)
If you don't want people to express opinions on code snippets or
suggestions, don't post them.˙ I think most regulars here (and
certainly Janis and Keith) will judge them as fairly as they can, on
the merits of the code - with a total disregard to who posts them.
(The exception is that many regulars have kill-filed some of the more
irksome posters.)
Don't imagine that people will treat your posts or code samples
specially.˙ You are not that important, and you haven't been posting
in c.l.c. long enough to have established much of a reputation
(positive or negative).
It would be a lot better if you stuck to writing posts that are
sensible replies within threads, or start new topical threads.˙ Post
C code, get feedback on it, and treat that feedback as constructive
criticism of the code - not as some kind of personal attack.˙ (My
post here is intended as constructive criticism - it is not a
personal attack.)
you think Policy tells you. The poster asked how to avoid if then else
and I showed him a way. It solved his problem. Where is the evil in
that? Who is this deity you worship that say to you you can gauge a
morality of a snippet of code based on your pathetic standards and
policies at YOUR company?
in fact i was talking about quite other and more theoretical problem,
not how rewrite tis pice of code (as to revrite i think the ones
˙with
˙char* a= "";˙ if(d<0.3) a ="barely" ; if(d>.9) a= "hardly";
slog("siunsusn %s", a);
is best)
On 09/09/2026 13:32, bart wrote:
On 09/09/2026 09:18, David Brown wrote:
On 08/09/2026 21:08, bart wrote:
On 08/09/2026 17:40, Scott Lurndal wrote:
bart <bc@freeuk.com> writes:
On 07/09/2026 23:50, Janis Papanagnou wrote:
˙ <snip>
The duplication is a problem. If 50 modules each includes the header >>>>>> files for a library such as SDL2, then a full build means a
scanning the
headers 50 times, which means 4000 header files (80 unique) and 2.5M >>>>>> lines of code (50K unique).
On a modern machine, this may add a few milliseconds to the build.
I don't think so. Here is a one-file test C program:
˙˙˙ '#include <SDL3/SDL.h>'
This is a test that compiles 50 copies of it:
˙˙˙ c:\sdl>tm gcc -c -I. s*.c
˙˙˙ TM: 36.59
That's 36,000 milliseconds, rather more than a few. (SDL3 is not
80Kloc rather than 50Kloc.)
I only happen to have SDL2/SDL.h on my machine, but I tested that :
$ cat s1.c
#include <SDL2/SDL.h>
$ time gcc -c s1.c
real˙˙˙ 0m0.223s
user˙˙˙ 0m0.184s
sys˙˙˙ 0m0.039s
$ for i in {2..50}; do cp s1.c s$i.c; done
$ time gcc -c s*.c
real˙˙˙ 0m10.088s
user˙˙˙ 0m8.600s
sys˙˙˙ 0m1.483s
$ touch s*.c
$ time make -j s*.o
real˙˙˙ 0m0.958s
user˙˙˙ 0m14.600s
Note that in my example above, the "extra resources, tools and
workarounds" was one line.
And again, let me reiterate the numbers from my real-world use-case.˙ In comparison to a serial build of all files in my project, these
"workarounds" improve my builds by a factor of 50 or more, compared to
your suggestion that could at most save about 10% if it managed to completely eliminate /all/ pre-processing time.
Using appropriate tools and development practices is not a "workaround",
it is common sense.˙ If you were a lumberjack rather than a programmer, you'd be using a flint axe and accusing chainsaw users as using
workarounds when really the answer is to grow trees without bark.˙ That really is the absurdity of your argument.
so conclusions were c lacks some language construct which i described as
case() {}
case() {}
case() {}
otherwise {}
On 09/09/2026 15:14, Lane W wrote:
David Brown wrote:
C's include system works well when used in a sensible and disciplinedAgreed. Plus some C programmers use the switch keyword, which we all
manner, but unfortunately not all C programmers are sensible and
disciplined.
agree is BAD BAD BAD, right Janis and Keith?
In fact at work, I'm regularly known as __The Evil One__ because of my
propensity to use the switch construct.
Every company brochure shows my position as Sauron in the company
fables, with my signature golden ring. Pure evil, I guarantee it.
I can't understand where this martyr complex comes from.˙ I saw your
post about an alternative way to structure fir's code, and I thought it
was a poor solution.˙ That was not because it used "switch", or
because /you/ wrote it, but simply because I did not think it was a
clear or maintainable way to express the algorithm.
fir wrote:
Lane W pisze:
David Brown wrote:
On 09/09/2026 15:14, Lane W wrote:It's˙ because many of the lot of you are tying your hands with what
David Brown wrote:
C's include system works well when used in a sensible andAgreed. Plus some C programmers use the switch keyword, which we
disciplined manner, but unfortunately not all C programmers are
sensible and disciplined.
all agree is BAD BAD BAD, right Janis and Keith?
In fact at work, I'm regularly known as __The Evil One__ because of >>>>> my propensity to use the switch construct.
Every company brochure shows my position as Sauron in the company
fables, with my signature golden ring. Pure evil, I guarantee it.
I can't understand where this martyr complex comes from.˙ I saw your
post about an alternative way to structure fir's code, and I thought
it was a poor solution.˙ That was not because it used "switch", or
because /you/ wrote it, but simply because I did not think it was a
clear or maintainable way to express the algorithm.˙ It added
complexity and a layer of indirection without adding advantages of
flexibility or clarity.˙ (I fully agree with your comment in the
post that there are many ways to structure the code here - without
knowing much more about the program, it is impossible to give a good
comparison to them.)
If you don't want people to express opinions on code snippets or
suggestions, don't post them.˙ I think most regulars here (and
certainly Janis and Keith) will judge them as fairly as they can, on
the merits of the code - with a total disregard to who posts them.
(The exception is that many regulars have kill-filed some of the
more irksome posters.)
Don't imagine that people will treat your posts or code samples
specially.˙ You are not that important, and you haven't been posting
in c.l.c. long enough to have established much of a reputation
(positive or negative).
It would be a lot better if you stuck to writing posts that are
sensible replies within threads, or start new topical threads.˙ Post
C code, get feedback on it, and treat that feedback as constructive
criticism of the code - not as some kind of personal attack.˙ (My
post here is intended as constructive criticism - it is not a
personal attack.)
you think Policy tells you. The poster asked how to avoid if then
else and I showed him a way. It solved his problem. Where is the evil
in that? Who is this deity you worship that say to you you can gauge
a morality of a snippet of code based on your pathetic standards and
policies at YOUR company?
in fact i was talking about quite other and more theoretical problem,
not how rewrite tis pice of code (as to revrite i think the ones
˙˙with
˙˙char* a= "";˙ if(d<0.3) a ="barely" ; if(d>.9) a= "hardly";
slog("siunsusn %s", a);
is best)
My concern here is that Keith Thompson is going to crucify you here
because you assigned a new value to 'a' after the previous one, which offends his exceedingly gentle sensibilities. How will you continue to
write C if you are nailed to one of Keith Thompson's crosses?
I'd choose a non-reserved name for the macro, probably
H_NUMBER_GENERATOR (not NUMBER_GENERATOR_H because that produces a
reserved name for a header whose name starts with 'e').
Janis Papanagnou wrote:
On 2026-09-09 02:47, Lane W wrote:
Keith Thompson wrote:
[...][...]
[...] You and Janis are opposed to my switch formulation because it
was me, yes me, Lane W.
How cocky (and completely wrong) to believe that my criticism of your
'if'/'switch' code was a personal thing; the keywords I provided as
hints should have made that very clear that it was really bad code;
and not only "bad" code.
(But now I see that there's indeed something evolving that is related
to your personality, but also to the quality of your posts' contents.
So I'll abstain from further seeing your contributions here. *p*)
I can see you are concerned about what is 'good' and 'bad' in
programming. It's not important whether it answers the question a poster asked. Oh no, you've got a couple 'standards' and 'policy' cards up your sleeve about what is right and good and Immaculate in programming. But
it's all dashed against the rocks as you exhibit the height of cowardice
by posting this lengthy screed only to say, goodbye, you're killfiled, sucker. I'm afraid I am extremely loathe to take morality lessons from a fleeing elf like yourself. Go back and cry to Lord Elrond of Rivendell
about the orc who programmed with switch.
I think it's okay if there's an argumentative relation or comparisonJanis just said he didn't like it. You've gone so far as to say it
was not relevant.
to make some point clear. (But there's also purists who don't agree
with that and shun or rebuke you for every non-C related reference.)
A simple "I think A is better than B." statement is in any case not
only an IMO stupid statement but it would require detailed off-topic discussions of A and of B, which are both unrelated to "C".
And I'm always astonished when people make such statement, regarding
tools or languages; my observation is that such people are regularly
judging from a very limited view of own experience or even just from
an isolated bubble. It's also not plausible that things are only B/W;
but that's where animosities grow. Nobody gets anywhere by that. Try
to avoid that.
Myself (and quite typical) knowing only a comparably small subset of
the meanwhile thousands existing programming languages I try to focus
on the good things that languages invented, and on their weak points.
But then there's also all this _repeated and enduring_ expression of disfavor. This is really annoying! And I wonder what these complaints
should accomplish. If someone finds "C" that disgusting (and A or B
"better") it would be consequent to move over and enjoy the presumed advantages of those choices in the respective group.
The only reason people still use C++ is because of its overall speed
from what I can tell.
This is another example of a unhelpful, even stupid formulations (even
when alleviating the core statement by a "from what I can tell" phrase. Speaking about "the only reasons", without evidence (and own knowledge
of the peoples' motivations), and (in the generalized form) of "people"
isn't confidence-inspiring as a base of discussion.
(Myself I'm not using C++ because of it's speed, and I don't avoid C#
because I wouldn't know it. - Accept that there's reasons beyond your
limited abilities of perception or imagination.)
Or else they haven't been cultured enough to experience C# yet.
A statement that can only be understood to have been made from a very
limited experience and knowledge, disregarding what's explained above.
(That statement could even be considered showing arrogance and being
rude; if it wouldn't be so stupid in the first place, and be ignored concerning it's content, these irrelevant and unfounded statements.)
What can be done to improve C#'s overall speed?
This is a question that would be topical in the appropriate C# fora.
fir pisze:
so conclusions were c lacks some language construct which i described as
case() {}
case() {}
case() {}
otherwise {}
this is in fact kinda 'typical' construct when some talk on cases
of usage so imo it could even be written in horizontal
case(d<.3) { slog("dodged hardly"); } case(d>.9) {slog("dodged
barely");} otherwise {slog("dodged");}
i mean it can be written vertical as only one of this subblocks will
execute
Janis Papanagnou pisze:
On 2026-09-09 10:38, David Brown wrote:
On 09/09/2026 10:13, Janis Papanagnou wrote:
On 2026-09-08 13:47, bart wrote:
On 08/09/2026 01:02, Waldek Hebisch wrote:
[...][...]
Still, modern languages tend to have a module scheme, suggesting
the 'flexible' C approach (I'd use the term 'prehistoric') wasn't
quite enough.
A necessary consequence of the growing systems and software
architectures. But even some legacy languages had already
modularization concepts back then! So it's not an excuse to
provide only a primitive #include mechanism. But I wouldn't
be so critical given the time when "C" had been designed.
You should take into account C's design-principles and also
when it came out and sort them in, in comparison to other
language schools; compare (for example) the release dates
of Pascal -> Modula (and what these two provided here).
AFAIK, Pascal originally did not have any kind of "unit" system (its
module equivalent) - you used textual inclusion files.˙ But you then
compiled everything as one big Pascal file rather than having
separate compilation.˙ (This may have varied between Pascal
implementations.)
Yes, exactly. - Original Pascal didn't have anything, then came "C"
timely - providing something that Pascal didn't have! - and Wirth's
next language Modula then had a concept.
Sorry if I was unclear.
Janis
note this pascal sign := is not stupid in some way but it has
disadvanteges - whose in best approach should be none
:= DIS 1) it has worse looking (look) than˙ =; note its important coz =
is much more simple much more clean its also˙ one type and is in ascii
:= ADV 2) it has sense of direction (compared to =)
:= DIS 3) it has only left right sense of direcion - and preferably it should have jet up down (so 4 possible versions)
= DIS 4) it collides with normal math world and normal world meaning of
"=" which are not quite assign - though it kinda painlessly may be used
to assign
it maybe come form basiclike
let a=2
without let a=2 is if-like hipothesis and let changes its meaning
so in c this let is like skipped and its standable. but.... (but there
are some subtle reservations
= ADV 5) it has also some advantage its traditional now/widely taken
(should not make thuis numbered list becouse i wanted to list := dis/adv
but then it shows i talk on =)
overally fact imo is assigns in c imo shouldnt be a=2 like,
you ned close dynamic sign but not this - i made 2 proposition there is
yet third
***************
*
***************
there are in fact more if this above is opened rectangle it also ould be opened traingle (but such noy high but more flat and so on),
even maybe this "harpoon" i mean liek arrow with no one˙ propeler blade (only one) ..harpoons maybe not such bad, (herpoon being lying 1 when
there also lying L is an option and so on)
On 09/09/2026 14:31, David Brown wrote:
On 09/09/2026 15:14, Lane W wrote:
David Brown wrote:
C's include system works well when used in a sensible andAgreed. Plus some C programmers use the switch keyword, which we all
disciplined manner, but unfortunately not all C programmers are
sensible and disciplined.
agree is BAD BAD BAD, right Janis and Keith?
In fact at work, I'm regularly known as __The Evil One__ because of
my propensity to use the switch construct.
Every company brochure shows my position as Sauron in the company
fables, with my signature golden ring. Pure evil, I guarantee it.
I can't understand where this martyr complex comes from.˙ I saw your
post about an alternative way to structure fir's code, and I thought
it was a poor solution.˙ That was not because it used "switch", or
because /you/ wrote it, but simply because I did not think it was a
clear or maintainable way to express the algorithm.
Agreed. It was poor, and there was still some duplication. It was also harder to tell whether the logic agreed with the original.
bart wrote:You have 3 near-identical calls to slog(). And in this new version, NEAT
On 09/09/2026 14:31, David Brown wrote:Here's a revision, where I take MORE THAN TEN SECONDS:
On 09/09/2026 15:14, Lane W wrote:
David Brown wrote:
C's include system works well when used in a sensible andAgreed. Plus some C programmers use the switch keyword, which we all
disciplined manner, but unfortunately not all C programmers are
sensible and disciplined.
agree is BAD BAD BAD, right Janis and Keith?
In fact at work, I'm regularly known as __The Evil One__ because of
my propensity to use the switch construct.
Every company brochure shows my position as Sauron in the company
fables, with my signature golden ring. Pure evil, I guarantee it.
I can't understand where this martyr complex comes from.˙ I saw your
post about an alternative way to structure fir's code, and I thought
it was a poor solution.˙ That was not because it used "switch", or
because /you/ wrote it, but simply because I did not think it was a
clear or maintainable way to express the algorithm.
Agreed. It was poor, and there was still some duplication. It was also
harder to tell whether the logic agreed with the original.
enum Dodges {
˙˙˙ NEAT : 1
˙˙˙ FLAWED : 2
˙˙˙ BARELY : 3
˙˙˙ UNSUCCESS : 4
};
enum Dodges d = UNSUCCESS;
if (dodge < 1)
˙˙˙ d = BARELY;
if (dodge < 0.9)
˙˙˙ d = FLAWED;
if (dodge < 0.5)
˙˙˙ d = NEAT;
switch (d)
{
˙˙˙ case NEAT:
˙˙˙˙˙˙˙ slog("%s easily dodged attack...",˙ being[k].name);
˙˙˙˙˙˙˙ return 1;
˙˙˙ case FLAWED:
˙˙˙˙˙˙˙ slog("%s hardly dodged attack...",˙ being[k].name);
˙˙˙˙˙˙˙ return 1;
˙˙˙ case BARELY:
˙˙˙˙˙˙˙ slog("%s dodged˙ attack...",˙ being[k].name);
˙˙˙˙˙˙˙ return 1;
˙˙˙ default:
˙˙˙˙˙˙˙ return -1; // not dodged.
}
WHERE IS THIS DUPLICATION?
On 09/09/2026 13:30, David Brown wrote:
On 09/09/2026 13:32, bart wrote:
On 09/09/2026 09:18, David Brown wrote:
On 08/09/2026 21:08, bart wrote:
On 08/09/2026 17:40, Scott Lurndal wrote:
bart <bc@freeuk.com> writes:
On 07/09/2026 23:50, Janis Papanagnou wrote:
˙ <snip>
The duplication is a problem. If 50 modules each includes the header >>>>>>> files for a library such as SDL2, then a full build means a
scanning the
headers 50 times, which means 4000 header files (80 unique) and 2.5M >>>>>>> lines of code (50K unique).
On a modern machine, this may add a few milliseconds to the build.
I don't think so. Here is a one-file test C program:
˙˙˙ '#include <SDL3/SDL.h>'
This is a test that compiles 50 copies of it:
˙˙˙ c:\sdl>tm gcc -c -I. s*.c
˙˙˙ TM: 36.59
That's 36,000 milliseconds, rather more than a few. (SDL3 is not
80Kloc rather than 50Kloc.)
I only happen to have SDL2/SDL.h on my machine, but I tested that :
$ cat s1.c
#include <SDL2/SDL.h>
$ time gcc -c s1.c
real˙˙˙ 0m0.223s
user˙˙˙ 0m0.184s
sys˙˙˙ 0m0.039s
$ for i in {2..50}; do cp s1.c s$i.c; done
$ time gcc -c s*.c
real˙˙˙ 0m10.088s
user˙˙˙ 0m8.600s
sys˙˙˙ 0m1.483s
$ touch s*.c
$ time make -j s*.o
real˙˙˙ 0m0.958s
user˙˙˙ 0m14.600s
So actual CPU time is 14 seconds?
Note that in my example above, the "extra resources, tools and
workarounds" was one line.
No, they were invoked in one line. Otherwise you're saying NASA didn't
need the Saturn 5 rocket, just the launch button!
And again, let me reiterate the numbers from my real-world use-case.
In comparison to a serial build of all files in my project, these
"workarounds" improve my builds by a factor of 50 or more, compared to
your suggestion that could at most save about 10% if it managed to
completely eliminate /all/ pre-processing time.
Using appropriate tools and development practices is not a
"workaround", it is common sense.˙ If you were a lumberjack rather
than a programmer, you'd be using a flint axe and accusing chainsaw
users as using workarounds when really the answer is to grow trees
without bark.˙ That really is the absurdity of your argument.
Wrong sort of analogy and the wrong sort of approach.
Let's try this one: you have a task to do, and it takes T time on a
certain machine using a certain tool. But now you need to it 50 times so
it would take 50T.
Your solution is to buy 10 machines each 5 times as fast so that all 50 tasks still complete in time T.
To me, just throwing resources at the problem is the wrong approach. Why aren't you looking at why the task takes T seconds in the first place?
In this case, I mentioned too approaches:
(1) Use a faster tool. I said that that TCC is considerably faster at
this stuff, taking 1.5s versus 38s on Windows. (It turns out windows.h, while it occurs in the headers, is not actually used, so both do the
same work.)
Now, TCC is very poor at generating executable code, however we're
talking about scanning declarations! There is no code; it only has to populate a symbol table. (Actually, there are a dozen small function defs.)
I'm not suggesting to use TCC, but gcc etc ought to work faster.
(2) Reduce the size of the task. I applied my tool to the SDL3 headers,
and the 86 files/82Kloc/3.6MB can be reduced to 1 file/4Kloc/0.18MB.
That is a *95% reduction in source code*.
Combine these two approaches, and you can be looking at a two magnitudes improvement in *raw* compilation speed. You might need to buy a smaller computer!
David Brown wrote:
On 09/09/2026 15:14, Lane W wrote:It's˙ because many of the lot of you are tying your hands with what you think Policy tells you. The poster asked how to avoid if then else and I showed him a way. It solved his problem. Where is the evil in that? Who
David Brown wrote:
C's include system works well when used in a sensible andAgreed. Plus some C programmers use the switch keyword, which we all
disciplined manner, but unfortunately not all C programmers are
sensible and disciplined.
agree is BAD BAD BAD, right Janis and Keith?
In fact at work, I'm regularly known as __The Evil One__ because of
my propensity to use the switch construct.
Every company brochure shows my position as Sauron in the company
fables, with my signature golden ring. Pure evil, I guarantee it.
I can't understand where this martyr complex comes from.˙ I saw your
post about an alternative way to structure fir's code, and I thought
it was a poor solution.˙ That was not because it used "switch", or
because /you/ wrote it, but simply because I did not think it was a
clear or maintainable way to express the algorithm.˙ It added
complexity and a layer of indirection without adding advantages of
flexibility or clarity.˙ (I fully agree with your comment in the post
that there are many ways to structure the code here - without knowing
much more about the program, it is impossible to give a good
comparison to them.)
If you don't want people to express opinions on code snippets or
suggestions, don't post them.˙ I think most regulars here (and
certainly Janis and Keith) will judge them as fairly as they can, on
the merits of the code - with a total disregard to who posts them.
(The exception is that many regulars have kill-filed some of the more
irksome posters.)
Don't imagine that people will treat your posts or code samples
specially.˙ You are not that important, and you haven't been posting
in c.l.c. long enough to have established much of a reputation
(positive or negative).
It would be a lot better if you stuck to writing posts that are
sensible replies within threads, or start new topical threads.˙ Post C
code, get feedback on it, and treat that feedback as constructive
criticism of the code - not as some kind of personal attack.˙ (My post
here is intended as constructive criticism - it is not a personal
attack.)
is this deity you worship that say to you you can gauge a morality of a snippet of code based on your pathetic standards and policies at YOUR company?
bart wrote:
On 09/09/2026 14:31, David Brown wrote:Here's a revision, where I take MORE THAN TEN SECONDS:
On 09/09/2026 15:14, Lane W wrote:
David Brown wrote:
C's include system works well when used in a sensible andAgreed. Plus some C programmers use the switch keyword, which we all
disciplined manner, but unfortunately not all C programmers are
sensible and disciplined.
agree is BAD BAD BAD, right Janis and Keith?
In fact at work, I'm regularly known as __The Evil One__ because of
my propensity to use the switch construct.
Every company brochure shows my position as Sauron in the company
fables, with my signature golden ring. Pure evil, I guarantee it.
I can't understand where this martyr complex comes from.˙ I saw your
post about an alternative way to structure fir's code, and I thought
it was a poor solution.˙ That was not because it used "switch", or
because /you/ wrote it, but simply because I did not think it was a
clear or maintainable way to express the algorithm.
Agreed. It was poor, and there was still some duplication. It was also
harder to tell whether the logic agreed with the original.
Can we get ten more people to hop on the bandwagon and RUDELY tell me
how bad it is?
On 08/09/2026 21:08, bart wrote:
On 08/09/2026 17:40, Scott Lurndal wrote:
4. Modern development is done with build systems - make, cmake, ninja, >bazel, whatever. The real work is done in parallel, making good use of
the multi-core machine. This also exasperates OS limitations - now
instead of dealing with a thousand file reads and a dozen processes for
one compilation, you are doing that twenty times in parallel. On *nix >systems, that's effortless - Windows has far more bottlenecks. And if
you have some kind of on-access anti-virus software running on the
Windows system, that can cripple performance.
I gauged that RUDENESS is something you try to avoid here.
On 09/09/2026 15:25, Lane W wrote:
bart wrote:You have 3 near-identical calls to slog(). And in this new version, NEAT
On 09/09/2026 14:31, David Brown wrote:Here's a revision, where I take MORE THAN TEN SECONDS:
On 09/09/2026 15:14, Lane W wrote:
David Brown wrote:
C's include system works well when used in a sensible andAgreed. Plus some C programmers use the switch keyword, which we
disciplined manner, but unfortunately not all C programmers are
sensible and disciplined.
all agree is BAD BAD BAD, right Janis and Keith?
In fact at work, I'm regularly known as __The Evil One__ because of >>>>> my propensity to use the switch construct.
Every company brochure shows my position as Sauron in the company
fables, with my signature golden ring. Pure evil, I guarantee it.
I can't understand where this martyr complex comes from.˙ I saw your
post about an alternative way to structure fir's code, and I thought
it was a poor solution.˙ That was not because it used "switch", or
because /you/ wrote it, but simply because I did not think it was a
clear or maintainable way to express the algorithm.
Agreed. It was poor, and there was still some duplication. It was
also harder to tell whether the logic agreed with the original.
enum Dodges {
˙˙˙˙ NEAT : 1
˙˙˙˙ FLAWED : 2
˙˙˙˙ BARELY : 3
˙˙˙˙ UNSUCCESS : 4
};
enum Dodges d = UNSUCCESS;
if (dodge < 1)
˙˙˙˙ d = BARELY;
if (dodge < 0.9)
˙˙˙˙ d = FLAWED;
if (dodge < 0.5)
˙˙˙˙ d = NEAT;
switch (d)
{
˙˙˙˙ case NEAT:
˙˙˙˙˙˙˙˙ slog("%s easily dodged attack...",˙ being[k].name);
˙˙˙˙˙˙˙˙ return 1;
˙˙˙˙ case FLAWED:
˙˙˙˙˙˙˙˙ slog("%s hardly dodged attack...",˙ being[k].name);
˙˙˙˙˙˙˙˙ return 1;
˙˙˙˙ case BARELY:
˙˙˙˙˙˙˙˙ slog("%s dodged˙ attack...",˙ being[k].name);
˙˙˙˙˙˙˙˙ return 1;
˙˙˙˙ default:
˙˙˙˙˙˙˙˙ return -1; // not dodged.
}
WHERE IS THIS DUPLICATION?
etc occur 3 times each (plus the enum names don't match what is printed
so are confusing).
Here's a version with only one call to slog:
˙ char* sdodge = NULL;
˙ if (dodge < 1.0)
˙˙˙˙˙ sdodge = " hardly";
˙ if (dodge < 0.9)
˙˙˙˙˙ sdodge = "";
˙ if (dodge < 0.5)
˙˙˙˙˙ sdodge = " easily";
˙ if (sdodge) {
˙˙˙˙˙ slog("%s%s dodged attack...", being[k].name, sdodge);
˙˙˙˙˙ return 1;
˙ }
This requires slog() changed to take an extra argument, or a wrapper created. It also corresponds more accurately to the original which I've pasted below.
On 09/09/2026 15:25, Lane W wrote:
You have 3 near-identical calls to slog(). And in this new version, NEAT
WHERE IS THIS DUPLICATION?
etc occur 3 times each (plus the enum names don't match what is printed
so are confusing).
Here's a version with only one call to slog:
char* sdodge = NULL;
if (dodge < 1.0)
sdodge = " hardly";
if (dodge < 0.9)
sdodge = "";
if (dodge < 0.5)
sdodge = " easily";
bart pisze:
This requires slog() changed to take an extra argument, or a wrapper
created. It also corresponds more accurately to the original which
I've pasted below.
slog is vararg so it can take it -
˙slog is just something like my screen log/memory log for text
quite useful and neat pice of code btw
On 09/09/2026 16:25, Lane W wrote:
I gauged that RUDENESS is something you try to avoid here.
If you don't want rude replies, don't make rude posts.˙ Ridiculous
sarcasm and exaggeration are not helpful.
fir pisze:
bart pisze:i see is should add the optimisation˙˙ if(&slog_[i][0]) ....
This requires slog() changed to take an extra argument, or a wrapper
created. It also corresponds more accurately to the original which
I've pasted below.
slog is vararg so it can take it -
˙˙slog is just something like my screen log/memory log for text
quite useful and neat pice of code btw
its maybe even quite noticable as this slog draw is called every frame
like 100 fps and it in turn calls her 500 calls to text draw helvetica
˙500 lines of memory log is much more than drawed on screen so it seems unnecsssary but i wanted it as a history to eventually "scroll up" and
see or flush to file etc
˙const int slog_line_max = 250;it also suggested using vsnprintf(&slog_[slog_top][0], slog_line_max,
˙const int slog_lines_max = 500;
˙char˙˙˙˙˙ slog_[slog_lines_max][slog_line_max];
˙int˙˙˙˙˙ slog_top = 0;
˙void DrawSlog()
˙{
˙˙ for(int i=0; i<slog_top; i++)
˙˙˙˙˙˙ if(&slog_[i][0])˙ text_xyc_helvetica( 10,helvetica_size*(i+3),0xe8e8e0,˙˙ &slog_[i][0]) ;
˙}
˙void ResetSlog() { slog_top = 0; }
˙void slog(char *format, ...)
˙{
˙˙˙˙˙ va_list args;
˙˙˙˙˙ va_start(args, format);
˙˙˙˙˙ vsprintf(&slog_[slog_top][0], format, args);
˙˙˙˙˙ va_end(args);
˙˙˙˙˙ slog_top++;
˙˙˙˙˙ if(slog_top>=slog_lines_max) slog_top=0;
˙ }
lol chatgpt corrected me indeed this if(&slog_[i][0]) cant be null at all as its place in ram table,
fir pisze:
fir pisze:it also suggested using˙ vsnprintf(&slog_[slog_top][0], slog_line_max, format, args); and turning˙ &slog_[i][0] into slog[i]
bart pisze:i see is should add the optimisation˙˙ if(&slog_[i][0]) ....
This requires slog() changed to take an extra argument, or a wrapper
created. It also corresponds more accurately to the original which
I've pasted below.
slog is vararg so it can take it -
˙˙slog is just something like my screen log/memory log for text
quite useful and neat pice of code btw
its maybe even quite noticable as this slog draw is called every frame
like 100 fps and it in turn calls her 500 calls to text draw helvetica
˙˙500 lines of memory log is much more than drawed on screen so it
seems unnecsssary but i wanted it as a history to eventually "scroll
up" and see or flush to file etc
˙˙const int slog_line_max = 250;
˙˙const int slog_lines_max = 500;
˙˙char˙˙˙˙˙ slog_[slog_lines_max][slog_line_max];
˙˙int˙˙˙˙˙ slog_top = 0;
˙˙void DrawSlog()
˙˙{
˙˙˙ for(int i=0; i<slog_top; i++)
˙˙˙˙˙˙˙ if(&slog_[i][0])˙ text_xyc_helvetica(
10,helvetica_size*(i+3),0xe8e8e0,˙˙ &slog_[i][0]) ;
˙˙}
˙˙void ResetSlog() { slog_top = 0; }
˙˙void slog(char *format, ...)
˙˙{
˙˙˙˙˙˙ va_list args;
˙˙˙˙˙˙ va_start(args, format);
˙˙˙˙˙˙ vsprintf(&slog_[slog_top][0], format, args);
˙˙˙˙˙˙ va_end(args);
˙˙˙˙˙˙ slog_top++;
˙˙˙˙˙˙ if(slog_top>=slog_lines_max) slog_top=0;
˙˙ }
lol chatgpt corrected me indeed this˙ if(&slog_[i][0])˙ cant be null
at all as its place in ram table,
bart pisze:
On 09/09/2026 15:25, Lane W wrote:
bart wrote:You have 3 near-identical calls to slog(). And in this new version,
On 09/09/2026 14:31, David Brown wrote:Here's a revision, where I take MORE THAN TEN SECONDS:
On 09/09/2026 15:14, Lane W wrote:
David Brown wrote:
C's include system works well when used in a sensible andAgreed. Plus some C programmers use the switch keyword, which we
disciplined manner, but unfortunately not all C programmers are >>>>>>> sensible and disciplined.
all agree is BAD BAD BAD, right Janis and Keith?
In fact at work, I'm regularly known as __The Evil One__ because
of my propensity to use the switch construct.
Every company brochure shows my position as Sauron in the company >>>>>> fables, with my signature golden ring. Pure evil, I guarantee it.
I can't understand where this martyr complex comes from.˙ I saw
your post about an alternative way to structure fir's code, and I
thought it was a poor solution.˙ That was not because it used
"switch", or because /you/ wrote it, but simply because I did not
think it was a clear or maintainable way to express the algorithm.
Agreed. It was poor, and there was still some duplication. It was
also harder to tell whether the logic agreed with the original.
enum Dodges {
˙˙˙˙ NEAT : 1
˙˙˙˙ FLAWED : 2
˙˙˙˙ BARELY : 3
˙˙˙˙ UNSUCCESS : 4
};
enum Dodges d = UNSUCCESS;
if (dodge < 1)
˙˙˙˙ d = BARELY;
if (dodge < 0.9)
˙˙˙˙ d = FLAWED;
if (dodge < 0.5)
˙˙˙˙ d = NEAT;
switch (d)
{
˙˙˙˙ case NEAT:
˙˙˙˙˙˙˙˙ slog("%s easily dodged attack...",˙ being[k].name);
˙˙˙˙˙˙˙˙ return 1;
˙˙˙˙ case FLAWED:
˙˙˙˙˙˙˙˙ slog("%s hardly dodged attack...",˙ being[k].name);
˙˙˙˙˙˙˙˙ return 1;
˙˙˙˙ case BARELY:
˙˙˙˙˙˙˙˙ slog("%s dodged˙ attack...",˙ being[k].name);
˙˙˙˙˙˙˙˙ return 1;
˙˙˙˙ default:
˙˙˙˙˙˙˙˙ return -1; // not dodged.
}
WHERE IS THIS DUPLICATION?
NEAT etc occur 3 times each (plus the enum names don't match what is
printed so are confusing).
Here's a version with only one call to slog:
˙˙ char* sdodge = NULL;
˙˙ if (dodge < 1.0)
˙˙˙˙˙˙ sdodge = " hardly";
˙˙ if (dodge < 0.9)
˙˙˙˙˙˙ sdodge = "";
˙˙ if (dodge < 0.5)
˙˙˙˙˙˙ sdodge = " easily";
˙˙ if (sdodge) {
˙˙˙˙˙˙ slog("%s%s dodged attack...", being[k].name, sdodge);
˙˙˙˙˙˙ return 1;
˙˙ }
This requires slog() changed to take an extra argument, or a wrapper
created. It also corresponds more accurately to the original which
I've pasted below.
slog is vararg so it can take it -
˙slog is just something like my screen log/memory log for text
quite useful and neat pice of code btw
˙const int slog_line_max = 250;
˙const int slog_lines_max = 500;
˙char˙˙˙˙˙ slog_[slog_lines_max][slog_line_max];
˙int˙˙˙˙˙ slog_top = 0;
˙void DrawSlog()
˙{
˙˙ for(int i=0; i<slog_top; i++)
˙˙˙ text_xyc_helvetica( 10,helvetica_size*(i+3),0xe8e8e0,
&slog_[i][0]) ;
˙}
˙ void ResetSlog()˙˙ {˙˙˙˙˙ slog_top = 0;˙ }
˙ void slog(char *format, ...)
˙˙ {
˙˙˙˙˙ va_list args;
˙˙˙˙˙ va_start(args, format);
˙˙˙˙˙ vsprintf(&slog_[slog_top][0], format, args);
˙˙˙˙˙ va_end(args);
˙˙˙˙˙ slog_top++;
˙˙˙˙˙ if(slog_top>=slog_lines_max) slog_top=0;
˙˙ }
On 09/09/2026 16:09, bart wrote:
I am looking at what /I/ can do to get the results I need in a timely fashion.˙ I am not interested in spending years making a new C compiler
just because it might be a bit faster than gcc - which sane customer
would pay me to do that?
˙I am not interested in spending days or weeks
trying to minimise and optimise the headers from manufacturer's SDKs and third-party libraries to shave a few percent off my built times.
TCC is, at best, a very niche tool.˙ It is not an alternative for
serious development work.
Now, TCC is very poor at generating executable code, however we're
talking about scanning declarations! There is no code; it only has to
populate a symbol table. (Actually, there are a dozen small function
defs.)
No one cares about the speed of scanning declarations.˙ The speed at
which actual programs are compiled can be relevant (though I have yet to
see it as an issue for my work).˙ It doesn't matter how quickly or
slowly a computer can do a useless task.
I'm not suggesting to use TCC, but gcc etc ought to work faster.
(2) Reduce the size of the task. I applied my tool to the SDL3
headers, and the 86 files/82Kloc/3.6MB can be reduced to 1
file/4Kloc/0.18MB.
That is a *95% reduction in source code*.
As I showed in my timings, in real use, that could, at most, reduce the compile time by about 15%.
Certainly, the line counts of big libraries are likely to dwarf that ofCombine these two approaches, and you can be looking at a two
magnitudes improvement in *raw* compilation speed. You might need to
buy a smaller computer!
You /know/ you are talking drivel here.˙ Either that or you are combing
a appallingly inefficient file handling with an extremely simplistic compiler, if you think that reading the header files is the dominant
time factor for actual real-world compilation of C code.
bart <bc@freeuk.com> writes:
On 09/09/2026 15:25, Lane W wrote:
You have 3 near-identical calls to slog(). And in this new version, NEAT
WHERE IS THIS DUPLICATION?
etc occur 3 times each (plus the enum names don't match what is printed
so are confusing).
Here's a version with only one call to slog:
char* sdodge = NULL;
if (dodge < 1.0)
sdodge = " hardly";
if (dodge < 0.9)
sdodge = "";
if (dodge < 0.5)
sdodge = " easily";
So you assign sdodge up to three times. A waste of cycles.
bart <bc@freeuk.com> wrote:
On 08/09/2026 01:02, Waldek Hebisch wrote:
bart <bc@freeuk.com> wrote:
On 07/09/2026 14:33, David Brown wrote:
On 07/09/2026 14:55, bart wrote:
A typical module scheme works like this:
* You have, say, a project of 100 modules
* Each module selectively exports some entities
* Each module selectively imports some subset of the other 99 modules >>>>>>
OK so far.
The result is that each module starts with some rag-tag collection of >>>>>> 'import' statements, each different from any other module, and needing >>>>>> a lot of maintenance.
No.˙ People who write /structured/ code do not do "rag-tag".
When a project is of a size where it is inconvenient to keep track of >>>>> all the separate "import" (or "#include", or whatever) statements, you >>>>> use a hierarchy.˙ Instead of importing "dns", "udp", "http", etc.,
modules, you import "network".˙ The common "network" module pulls in the >>>>> sub-modules.˙ You probably also organise things in directories and sub- >>>>> directories, matching the module layout.˙ It is /structured/.
But it's a pattern I've seen a lot. In C also, as collections of
#includes; this example is from Lua, a project of only 35 modules, and >>>> from one of its .c files:
#include "lprefix.h"
#include <float.h>
#include <limits.h>
#include <math.h>
#include <stdlib.h>
#include "lua.h"
#include "lcode.h"
#include "ldebug.h"
#include "ldo.h"
#include "lgc.h"
#include "llex.h"
#include "lmem.h"
#include "lobject.h"
#include "lopcodes.h"
#include "lparser.h"
#include "lstring.h"
#include "ltable.h"
#include "lvm.h"
Every file has a different set. In all, there are 28K lines of C code
among the .c files, and there are 466 #include lines. That is similar to >>>> the maintenance nightmare where each file imports a particular set of
modules.
The organization looks sensible to me.
Not to me. This project uses these 35 files:
lapi.c lauxlib.c lbaselib.c lcode.c lcorolib.c lctype.c ldblib.c
ldebug.c ldo.c ldump.c lfunc.c lgc.c linit.c liolib.c llex.c
lmathlib.c lmem.c loadlib.c lobject.c lopcodes.c loslib.c lparser.c
lstate.c lstring.c lstrlib.c ltable.c ltablib.c ltests.c ltm.c lua.c
lundump.c lutf8lib.c lvm.c lzio.c onelua.c
(A build will use 34 of them, depending whether it is EXE or DLL.)
With a module scheme, there should be no need for any additional info at
all. But my point was, with how such schemes typically work, you still
have lots of mixed sets of 'import' statements at the start of each file.
Given that #include lines
are less than 2% of total and are likely to change very infrequently
I see no maintennce problem.
You can't quantify it like that. In any case, they will only change
infrequently once you've finished development!
If a program is "finished" it will not change at all. During
normal developement I need to add #include lines, but once
added they tend to stay. Sometimes I realize that given
include is not needed or I decide to rename a file. Normal
code is different, first version may have bugs which need
fixing, I may realize that different structure is better, so
there is lot of changes. Relatively to that I perceive changes
to #include lines to be very infrequent.
I found it annoying enough, and taking up enough time to devise a new
way of doing modules. And it is utter bliss.
I agree that maintaing info that you do not value may be annoying.
But if you are used to maintaing C code bases, than maintaining
#include lines does not take much time.
Still, modern languages tend to have a module scheme, suggesting the
'flexible' C approach (I'd use the term 'prehistoric') wasn't quite enough.
I used or at least looked at several languages with module systems
or things intended to perform similar duty. You approach seem to
be unique, all other require explicit import or equivalent at least
in some (rather frequent) cases. Some languages do not support
re-export, in such case you can rightfully complain. The ones with
re-export allow forming common interface module do that number
of import statements is minimised. But this is developers choice
and apparently most prefer to import only needed things, even
though it requires more import statements.
Module system has other advantages over C. First, in C sane
developers use headers in consistent way, but language
does not enforce it. Typical module system enforces
consistency. Second, module interfaces can be parsed once,
avoiding problem of repeated re-parsing of C headers.
Third, modules resolve name clashes: the "same" name in
two different modules is disambiguated by its source module.
Fourth, given a main module compiler can track its imports
and build the program without need for separate Makefile.
There are different styles. Ada, Modula 2 and Extended Pascal
use separate interface modules. In typical practice they are
stored in separate files so this looks similar to C practice
of having .c and .h files. Other languages like UCSD/Turbo
Pascal have modules with separate iterface and implementation
parts, but both parts are considered a single module. In
practice with such languages whole module is kept in a single
file, so number of separate files is smaller. But you still
have separate declarations in interface part and definitions
in implementation part. Wirth Oberon (or at least some variant
of it) uses different apprach, IIRC exported functions are
marked putting asterisk before function name. That means less
code to write, but to see what is exported you need a separate
tool.
IIUC modules with separate iterface and implementation were
advocated together with database-like storage of source code.
| Sysop: | Tetrazocine |
|---|---|
| Location: | Melbourne, VIC, Australia |
| Users: | 9 |
| Nodes: | 8 (0 / 8) |
| Uptime: | 15:34:31 |
| Calls: | 220 |
| Files: | 21,513 |
| Messages: | 84,315 |