• Official list of top C annoyances

    From fir@3:633/10 to All on Sun Sep 6 15:45:30 2026
    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)

    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From fir@3:633/10 to All on Sun Sep 6 15:52:08 2026
    yet i forgot that == is annoying it should be = but the assigment should
    be something like IL rotated 90 degress right something more like ? but
    more close to =

    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From bart@3:633/10 to All on Sun Sep 6 16:52:44 2026
    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

    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)


    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

    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Janis Papanagnou@3:633/10 to All on Sun Sep 6 21:41:23 2026
    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)?

    Or do you just not "like" typed languages? (Want more scripting?)

    I suppose you are using the wrong language for your liking, and
    complain in the wrong newsgroup.


    ITS TERRIBLE ANNOYING AND USELESS

    Strange that you find a principle like that - one that you find
    in most typed programming languages, I'd say! - "terrible".

    (It may annoy _you_, but it's certainly not "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)

    Given the many typing errors you make I understand that you want
    to have less to type.

    I'm currently programming mostly in a language that supports your
    preferred syntax rule, but I have no problem if a language doesn't.


    2) that i need end line with ";" (where newline sign should work

    You're obviously in the wrong newsgroup. It's typical that semantic
    phrases are separated by delimiters (or, in "C", by terminators).
    Again, I'm positive that is a common principle to define languages;
    notable exceptions are many scripting languages.

    You should think about what you buy, language design-wise, with the
    decision to allow newlines instead, or to allow both.

    Or just switch the language you are currently using and complaining
    about.


    3) that "," operator dont work in many cases

    Not sure what you mean here.

    Operators work on entities of their defined types and return a result
    of some type.

    Personally I have a critical view on considering the ',' as _operator_
    in the first place (in "C"). Mostly it's used in programming languages
    as a syntactical delimiter (that defines, for example, collaterality).


    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

    But that's how it was initially defined and it's use is still possible
    (if you consider subtle differences to '&&' and '||'). - But you won't
    do anyone a favor if you use a language in your own - debatable! - way,
    at least in cases where you'd cooperate with other people.

    In your own program writing activities use the construct that you like.


    5) *p.s works bad

    It works as it's defined. And with the preferences as defined. (It's
    also common in other languages to have struct-selectors bind strongly.)

    What's "bad" about it? - If you intended to have a semantics of (*p).s
    then just use p->s as it's been supposed.

    (It may help to you learn the language you intend to use, before using
    it.)

    If you think "C" is badly defined, generally or concerning precedence
    (with that or generally), just switch to a language that better suits
    you.



    and yet few things

    (i was writing on all this already but i hjust think official list
    should be written)

    Most things are either opinion and personal preferences (or just plain ignorance). There's no use for a list; there'd be as many such lists as
    there's people who are picky about some detail and think their opinion
    is representative.



    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.

    And it would be good (for all) if "fir" would just use your language,
    and stop all the whining.


    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).

    Check.


    * 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

    Check.

    Janis


    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From fir@3:633/10 to All on Mon Sep 7 09:37:12 2026
    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)

    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From David Brown@3:633/10 to All on Mon Sep 7 09:53:22 2026
    On 06/09/2026 21:41, Janis Papanagnou wrote:
    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)?


    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. When restricted to just that, it is not
    an entirely unreasonable wish. (Whining about having to jump back and
    forth in the code between your list of static forward declarations and
    the function you are writing is, on the other hand, entirely
    unreasonable. Editors that let you have two windows into the same file,
    or a split in the one window, have been standard for decades.)

    In general, declaring identifiers before using them is extremely helpful
    for static checking to avoid mistakes. And it is also helpful for those
    that are not great at typing, as their editors can auto-complete
    identifiers.



    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From bart@3:633/10 to All on Mon Sep 7 11:35:39 2026
    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).




    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Chris M. Thomasson@3:633/10 to All on Mon Sep 7 04:06:24 2026
    On 9/6/2026 8:52 AM, bart wrote:
    [...]
    * 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

    Might as well use Q#:

    https://learn.microsoft.com/en-us/azure/quantum/qsharp-overview

    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From David Brown@3:633/10 to All on Mon Sep 7 13:15:22 2026
    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, and when everything is
    written by one person (obviously that's fine for your personal
    language), it does not scale well. A "proper" modules system can handle multiple files or modules in a project with the same name (even C can
    handle that), and multiple identifiers of the same name (C fails there).


    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.

    Note that if you are using C++, it would be natural to use namespaces
    and inline variables :

    screens.h :

    namespace screens {
    inline int quest_screens = 123; // Optional initialisation
    }

    The choice of "inline" as the keyword here may seem odd - think of it as
    being "for historical reasons". It lets you define, not just declare,
    the variable in the header - but definitions are merged at link-time.
    So you don't have to have a separate "int quest_screens = 123;" in a
    .cpp file. (If the OP actually has any interest in moving to C++, the discussion should be moved to or restarted in c.l.c++.)

    There's a lot of features and complexity in C++ that many people
    dislike, for good or bad reasons. But it is also possible to pick a
    small subset of features and just use those - especially if you want to
    work in a language that is basically C, but with a few added features.


    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. That's always the difference between a one-man language and mainstream languages.



    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Johann 'Myrkraverk' Oskarsson@3:633/10 to All on Mon Sep 7 20:05:52 2026
    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!
    --
    Johann | email: invalid -> com | http://www.myrkraverk.com/blog/
    I'm not from the Internet, I just work there. | via Easynews.com https://bsky.app/profile/myrkraverk.bsky.social | for ( ;; ) _:;

    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From bart@3:633/10 to All on Mon Sep 7 13:55:21 2026
    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.

    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From fir@3:633/10 to All on Mon Sep 7 15:20:35 2026
    bart pisze:
    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:


    i think you should know i understand c

    you know when i open my new project it is build form number of c files
    usually few tens of .c files

    i also use my own library green.fire.dll

    i accept adding one header for green_fire.h but it is all my headers i
    need (i also use windows.h) i dont need any other .h files for
    mi internal c files - as this project is not divided
    on mode dll's /objects (object files)

    so it is clearly SILLY to add h headers for internal purposes imo

    so this is clearly annoyance

    (and you seem to know that as you was once discussing
    i remember that you use the same thing you call as i
    remember 'unity biulds'

    those internal headers are silly thing, and those predeclarations is
    silly thing

    (no need to discuss it as its clear thing imo)

    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From fir@3:633/10 to All on Mon Sep 7 15:24:40 2026
    bart pisze:
    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

    typical project (i mean medium sized which is like 100k lines or less is
    not 100 modules its 100 files and its one module

    in a sense what c calls module and windows calls modules (dlls)

    thats kinda problem as files should not need headers

    so if my 100 files are for modeule which makes dll i will make .h file
    but if its exe i will make no one

    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From fir@3:633/10 to All on Mon Sep 7 15:32:03 2026
    Johann 'Myrkraverk' Oskarsson pisze:
    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.


    back then i wrote a larger thread why say c++ like
    (though they are parralel concept so i woulnd we it to c++)
    are good thing and c pointers are maybe also good thing but
    much less usefull..so partially i could agree

    though what i mention here are more "shallow"
    annoyances not things that would mean the bigger changes of c in other language (those other changes are also present but this is kinda other
    thing)

    thise annoyances i mention probbaly should be changed in c standard (or
    at least maybe it could, some of them are backward compatible - liek or
    three first i mentioned

    it is
    1) make symbols be wisible down not only up
    2) add ad hoc enums/tags ('something')
    3) make ";" optional if there is newline instead
    4) maybe extend "," to work in more case to awid many {}



    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!


    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From David Brown@3:633/10 to All on Mon Sep 7 15:33:12 2026
    On 07/09/2026 14:55, bart wrote:
    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


    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/.

    One of the things some developers were concerned about in C++ is that
    when you do this with #include's, compile times increase significantly -
    so people often tried to minimise the number of #include's. (For C,
    this is far less of a problem except perhaps for a few very bloated
    headers.) C++ modules reduce this effect to almost nothing.


    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.


    As long as you have a reasonably organised structure, extra imports are
    rarely an issue (though it can be nice to remove them when tidying up). Renaming modules or files is never something done lightly in serious
    work, once the code is established - it means changes in your version
    control, and coordination across groups of developers. Changing the
    name in an "import" statement is a minor part of that, and it is not
    going to be forgotten. It is also something that can often be automated
    with refactoring tools in good IDEs (which are very helpful in
    navigating large projects).

    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.


    The trick is, don't write code that is an unstructured collection of 100 modules. Structure and organise your code.

    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 your code is structured. Then you don't need - or want - a system
    that throws everything together in one pot.

    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.

    It sounds far more like a way to keep things cluttered and disorganised.

    There is always a balance to be found between explicit and implicit, at
    all levels. Different people, and different projects, will look for
    different balance points. I can't say that your system appeals to me,
    as described here, but I accept that it suits you and the way you like
    to work. So I am not saying there is something wrong with the way you implement modules in your language, for your use in your projects -
    merely that it is not a scheme that would be considered ideal for other languages.


    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.


    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.

    (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.)


    (Agreed - there is no fixed language-agnostic definition of "module".)

    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!).

    It's not bad, and works well with the language.

    "Simple" is not a good thing in and of itself. Nor is "complex". A
    "simple" solution can be great in small use-cases, but painful in bigger projects - and vice-versa.


    ˙ 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.

    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.)



    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From bart@3:633/10 to All on Mon Sep 7 16:34:39 2026
    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.

    This is the project info for my C compiler project (the contents of
    cc.m, the module submitted to the compiler):

    module cc_cli

    module cc_decls ! Global Data and Tables
    module cc_tables

    module cc_lex ! Lexing and Parsing
    module cc_parse

    module cc_genpcl ! Generate PCL (IL)
    module cc_blockpcl
    module cc_libpcl

    module cc_lib ! Misc
    module cc_support

    module cc_headers ! Bundled (embedded) headers

    module cc_show ! Diagnostics

    $sourcepath "c:/mx/"
    import pcl ! IL Backend

    It shares a backend with the compiler for my own language; that one
    lists 20+ other modules via that import statement.

    So about 40 modules which are each specified exactly once. (Well, there
    can be different versions of the above, each for a different configuration.)

    This is it in action (the -r in each case will run the compiled program
    in memory):

    c:\cx>mm -r cc -r hello
    Compiling cc.m to cc.(run)
    Compiling hello.c to hello.(run)
    Hello, World!


    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.

    And the trick also is, don't try and force a hierarchical structure when
    there isn't one. My previous module schemes were strictly hierarchical;
    it didn't work.

    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.

    Lots of projects have 100 files or less. 100 files at 1Kloc/file average
    is 100Kloc, or about a 1MB binary (for a language at C's level compiled
    for x64).

    In my Windows' System32 folder, some 90% of EXE and DLL files are under 1MB.

    In my gcc installation, 97% of lib*.a files are under 1MB.

    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.


    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.)

    This is where I keep it simple: one file = one module = one namespace.

    Although other namespaces can be created with records (I guess classes
    in C++) and functions.

    (The latter is not possible in C++ AFAIK. You can do this for example:

    proc F =
    const x = main.y + 100 # x/y are compile-time constants
    end

    proc main =
    const y = 76
    println F.x # 176
    end

    This could allow two functions to share a private static variable (not
    locals or parameters).)




    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Janis Papanagnou@3:633/10 to All on Mon Sep 7 23:59:43 2026
    On 2026-09-07 09:53, David Brown wrote:
    [...]

    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.˙ [...]
    Thanks. Your explanation makes sense.

    Janis


    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Lane W@3:633/10 to All on Mon Sep 7 16:04:06 2026
    Janis Papanagnou wrote:
    On 2026-09-07 09:53, David Brown wrote:
    [...]

    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.˙ [...]
    Thanks. Your explanation makes sense.

    Janis

    I work mostly in C# where this isn't an issue anymore.

    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Janis Papanagnou@3:633/10 to All on Tue Sep 8 00:50:46 2026
    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).

    (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.

    Janis

    [...]


    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From bart@3:633/10 to All on Tue Sep 8 00:35:50 2026
    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:

    * 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.)

    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.


    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Lane W@3:633/10 to All on Mon Sep 7 17:43:42 2026
    bart wrote:
    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:

    * 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.)

    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.


    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Keith Thompson@3:633/10 to All on Mon Sep 7 16:52:33 2026
    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.

    --
    Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
    void Void(void) { Void(); } /* The recursive call of the void */

    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Waldek Hebisch@3:633/10 to All on Tue Sep 8 00:02:06 2026
    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.

    --
    Waldek Hebisch

    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Janis Papanagnou@3:633/10 to All on Tue Sep 8 03:11:55 2026
    On 2026-09-08 01:35, bart wrote:
    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:
    [ big snip ]
    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 seem to recall that you weren't using Makefiles (or similar) to
    organize your projects? - We did that, and we had never any naming
    issues in our projects. - I don't recall every detail, but we used
    hierarchical Makefiles for sub-components, we had libraries with
    well defined (usually terse and clean) interfaces to be im/exported
    from/to parallel working groups, the same for interoperability with
    groups on other sites and in other companies we cooperated with in
    our huge projects, naming conventions on every "interface" (in depth
    and width dimension); not everyone needed to see every file.

    [...]

    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.

    What I was saying was that if you use programming languages that don't inherently support a good modularization concept you should take action
    to structure your (sub-)project(s) accordingly. And I'm also suggesting
    that you should apply principles that 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.

    I'm unsure what exactly you feel "was complex", and what you think is "Linux-centric"; I recall your inability or unwillingness to make use
    of 'make' (which is available not only on the Unix platforms); in some multi-platform projects we used it flawlessly on/with various OSes.

    If you had "failed" (as you say) you might have needed to spend a bit
    more time "learning" that - it's not difficult, though -, or get some
    external build-management expertise. (In our larger projects we had own "build-managers" who also provided standards, but most developers were
    able to write, modify, or extend Makefiles.)

    (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?

    I call that: "A process to create a binary."

    Try to distinguish the concepts of projects (with its many tasks from
    planning, resource allocation (all sorts of resources!), specification,
    design, implementation, testing, etc. etc.), processes that are set up
    for development, and the artifacts that various process phases create
    (like tar-files, archives, executables, test-results, documentation,
    etc. etc.). - Please note that this is an unsystematic and incomplete
    list of entities, just as examples and off the top of my head; inspect
    some project management sources to learn about projects. (The documents
    from my own, meanwhile expired IPMA certificate spans 2500 pages; it's
    nothing suited for private "toy projects", but there's principles that
    can be applied also to low-scale software development. - Don't expect
    that I make a try to explain substantial amounts of project management
    basics to a person who is known to notoriously avoid even Makefiles.)


    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.

    Fine.

    Janis


    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From David Brown@3:633/10 to All on Tue Sep 8 09:25:22 2026
    On 08/09/2026 00: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.)

    It is almost universal practice to have such include guards in header
    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.


    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From fir@3:633/10 to All on Tue Sep 8 12:59:49 2026
    fir pisze:
    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


    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

    really to dis day i not quite memorized how to handle them (i write my
    own and assume compiler optimise it but it is not how it should be)

    7) LACK OF UNPACKING

    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















    (i was writing on all this already but i hjust think official list
    should be written)


    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From fir@3:633/10 to All on Tue Sep 8 13:09:01 2026
    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



    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From bart@3:633/10 to All on Tue Sep 8 12:47:11 2026
    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.


    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From David Brown@3:633/10 to All on Tue Sep 8 14:15:28 2026
    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.


    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From fir@3:633/10 to All on Tue Sep 8 14:35:26 2026
    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 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.

    im not using macros

    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From fir@3:633/10 to All on Tue Sep 8 14:49:50 2026
    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 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.

    im not using macros


    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From bart@3:633/10 to All on Tue Sep 8 14:54:31 2026
    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.


    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From David Brown@3:633/10 to All on Tue Sep 8 16:05:39 2026
    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 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.

    im not using macros



    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From fir@3:633/10 to All on Tue Sep 8 16:10:52 2026
    bart pisze:
    On 08/09/2026 11:59, fir wrote:
    fir pisze:

    5) *p.s works bad

    You need either (*p).s here or p->s


    i was ance talking about that and i may not even remember my conclusions
    (some deeper conclusions are more deep in my head it seems and not easy
    to get immediatelly) but i hope my older conclusion not colide with a
    this opinion that

    *p.s shold jus be as (*p).s, if s is also a pointer then *p.*s
    and so on

    the way it is in c is terrible annoyance




    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.

    ye good point but some may use alternative like f.byte[3] (or char)
    or something, this should work

    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.


    what i say its not a final specification here as syntax detail would
    need to be chosen yet etc but lask ot this is annoying as hell


    and dont say it is easy to write macros, i wroite a bit of this unpacking/acking codes and it is ugly and bad way to code this..
    if you want efficiency (and you usually want in such types of codes,
    in my case relatet to RGB pixel opartions you need yet to experiment and
    test it for efficiancy

    using union really helps(as i was already written back then) but using
    union here is better than raw bitwise shifts atec but still much worse
    than builtin good language support

    (so both this minmax thing and this lack of pack/unpack) are serious c annoyances

    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From fir@3:633/10 to All on Tue Sep 8 16:18:42 2026
    David Brown pisze:
    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 wouldnt use a word genius but the fact is my opinions on language
    solutions in area of c are more grounded/solid than usual choices of
    people in language area imo

    in recent years i do not code (though i already written my own x86
    assembler) and halfo of a compiler (of some kind of proto-extended-c)
    it compiles things but as now im not code too much i feel no urge to try finish it (i feel not in good helth for longer focus work sadly0

    BUT more to say this kind of work to deduce what its should be in that
    improved c is much more hard and time consuming than writing compiler..

    many people can write a compiler but make some good decisions here it
    seems not so many can ;c

    though now i treat it more as a form of entertainment than regular work
    (as back then)






    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
    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.

    im not using macros




    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Lane W@3:633/10 to All on Tue Sep 8 09:45:12 2026
    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?


    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Scott Lurndal@3:633/10 to All on Tue Sep 8 16:40:36 2026
    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.

    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From David Brown@3:633/10 to All on Tue Sep 8 20:41:24 2026
    On 08/09/2026 17:45, Lane W wrote:
    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++.


    It is not really appropriate to talk here about C++ like this either -
    but it shows "fir" that what he claims he wants is achievable already,
    if he were serious and realistic.

    C++ is a language that grew out of C with extensions, and is closely
    related. C# is a managed language primarily targeting a specific OS,
    which grew out of MS's tantrums when they were not allowed to screw up
    Java and make it Windows-only without changing the language name. Now,
    it may well be that C# is "better" than Java, for some definition of
    "better" - I neither know nor care about either language. It may even
    be that C# is "better" than C++ in some ways - again, I don't know and
    don't care. But while C++ can be viewed as "C with accumulated extra features", with C as an approximate subset, C# is a significantly
    different language. It might occasionally be relevant in a c.l.c.
    thread in a "compare and contrast" discussion, just like Python or
    Fortran might be - but no more than that.

    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?


    That may be an interesting question, but it is /definitely/ one for a C# group, not a C group.



    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From bart@3:633/10 to All on Tue Sep 8 20:08:56 2026
    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.)

    My idea to flatten the headers into one file would reduce them to a
    fraction of the original, perhaps 0.25mb. No need for GCH files, and it benefits every compiler.

    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".

    All timings I post about about build-times take account of that and
    assume files are cached. The SDL3 headers are anyway only about 3.6MB.

    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.

    The overheads of compiling multiple header files, in fact anything I
    mentioned about build-systems, is always a non-problem according to you.

    That's why all these solutions and workarounds exist!

    Actually the last time I worked on an SDL project, not mine, each of the
    20 modules did in fact include SDL.H.


    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Chris M. Thomasson@3:633/10 to All on Tue Sep 8 12:39:25 2026
    On 9/8/2026 8:45 AM, Lane W wrote:
    [...]
    What can be done to improve C#'s overall speed?


    Get rid of the GC? ;^)

    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Chris M. Thomasson@3:633/10 to All on Tue Sep 8 12:47:45 2026
    On 9/7/2026 6:33 AM, David Brown wrote:
    [...]
    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.)

    Actually, I am quite fond of header only. ct_main.cpp is the main driver
    in my experimental system.

    lol. Here it is. Works fine for my current needs.

    https://i.ibb.co/S4Kx54Pk/image.png

    __________________________
    #include "ct_vector_grid.hpp"
    #include "ct_circle_tangent.hpp"
    #include "ct_ball_bearing.hpp"
    #include "ct_vector_fractal_tips.hpp"
    #include "ct_visions.hpp"
    #include "ct_vector_accum_test.hpp"
    #include "ct_bifurcation_test.hpp"
    #include "ct_tile_map_test.hpp"
    #include "ct_triangle_test.hpp"
    #include "ct_tile_test.hpp"
    #include "ct_vector_fractal_test.hpp"
    #include "ct_ttr.hpp"
    #include "ct_vector_dla_test.hpp"
    #include "ct_vector_cluster_test.hpp"
    #include "ct_povray_vector_field.hpp"
    #include "ct_colorbook.hpp"
    #include "ct_vector_field.hpp"
    #include "ct_koch_test.hpp"
    #include "ct_geometry_plot.hpp"
    #include "ct_cairo.hpp"
    #include "ct_glm.hpp"
    #include "ct_complex.hpp"


    #include <iostream>
    #include <stdexcept>
    #include <string>
    #include <cstdlib>


    void
    ct_main(
    char const* filename
    ) {
    ct::plane::plane_2d plane(
    ct::plane::axes_2d({ { 0, 0 }, 1.5f }),
    1920 / 1,
    1080 / 1

    // roxy test!
    // 512,
    // 512
    );

    ct::plot::cairo::plot_2d plot(plane);

    plot.clear({ 0, 0, 0, 1 });

    {
    ct::vector_grid::test::manifest(plot);


    //ct::circle_tangent::test::manifest(plot);

    //ct::ball_bearing::test::manifest(plot);

    //ct::vector_fractal_tips::test::manifest(plot);

    // ct::visions::manifest(plot);


    //ct::vector_accum_test::manifest(plot);

    //ct::bifurcation_test::manifest(plot);

    //ct::tile_map_test::manifest(plot);

    //ct::triangle_test::manifest(plot);

    //ct::tile_test::manifest(plot);

    //ct::vector_fractal_test::manifest(plot);

    //ct::ttr::manifest(plot);

    //ct::geometry::plot2d::manifest(plot);

    // ct::vector_field::manifest(plot);

    //ct::colorbook::manifest(plot);

    // ct::vector_cluster_test::manifest(plot);

    //ct::vector_dla_test::manifest(plot);

    //ct::plot::povray::manifest(plot);

    //ct::povray::vector_field::manifest(plot);
    }

    // Unit circle...
    plot.circle({ { 0, 0 }, 1 }, { 1, 1, 1, 1 }, 1);

    plot.save(filename);
    }



    int
    main()
    {
    std::cout << "ct_plot\n";
    std::cout << "by: Chris M. Thomasson\n";
    std::cout << "_________________________________________________" << std::endl;

    int status = EXIT_FAILURE;

    try
    {
    ct_main("./ct_output.png");

    // I know I know... ;^)
    std::system("mspaint ct_output.png");

    status = EXIT_SUCCESS;
    }

    catch (std::runtime_error const& error)
    {
    std::cerr << error.what();
    }

    catch (...)
    {
    std::cerr << "Shit hit the fan... ;^o\n";
    }

    std::cout << "\n_________________________________________________"
    << std::endl;

    return status;
    }

    __________________________



    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Keith Thompson@3:633/10 to All on Tue Sep 8 15:55:52 2026
    Lane W <cactus_DAC@yahoo.com> writes:
    [87 lines deleted]

    I don't understand why it's okay to talk about C++ here but not C#?

    It isn't.

    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.

    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.

    What can be done to improve C#'s overall speed?

    There are places where you can ask that question and get meaningful
    answers. This is not one of those places. If you can't find an
    appropriate newsgroup (there doesn't seem to be a comp.lang.csharp),
    there are plenty of forums other than Usenet.

    Also, when you post a followup, please trim any quoted text that
    isn't relevant your followup.

    --
    Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
    void Void(void) { Void(); } /* The recursive call of the void */

    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Lane W@3:633/10 to All on Tue Sep 8 18:02:14 2026
    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.

    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Keith Thompson@3:633/10 to All on Tue Sep 8 17:39:04 2026
    Lane W <cactus_DAC@yahoo.com> writes:
    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.

    No, you don't understand. It's not about whether the information
    is true or false.

    You seem to think that it's an objective fact that C# is better
    than C++. It's not. It's an opinion. But that's not what I was
    talking about.

    My complaint has nothing to do with whether C++ or C# is the superior
    language. (You'll note that I have not expressed an opinion.)
    My complaint is that you are posting in comp.lang.c about things
    that are not C.

    Repeatedly posting on comp.lang.c that C++ is better than C# is
    inappropriate, because it's off topic.

    Repeatedly posting on comp.lang.c that C# is better than C++ is
    inappropriate, because it's off topic.

    If you want to argue that one language is better than another, let
    me direct your attention to comp.lang.misc. I might even join in.

    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 (The_Other_Keith) Keith.S.Thompson+u@gmail.com
    void Void(void) { Void(); } /* The recursive call of the void */

    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Lane W@3:633/10 to All on Tue Sep 8 18:47:39 2026
    Keith Thompson wrote:

    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.

    Well aren't you a fancy ancy.

    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.

    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Keith Thompson@3:633/10 to All on Tue Sep 8 18:19:13 2026
    Lane W <cactus_DAC@yahoo.com> writes:
    Keith Thompson wrote:
    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.

    Well aren't you a fancy ancy.

    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.

    (It's conceivable that I did write something about it. If so,
    can you cite the relevant post of mine?)

    I wrote above that "I don't recall seeing *any* relevant posts
    here from you." That was literally true, but I'll concede that
    you probably have made some topical posts here.

    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.

    If you're talking about your "switch formulation", I have no opinion to
    back up.

    I'm asking you to (a) refrain from making posts here in comp.lang.c
    that have nothing to do with C (including claims that C# is better
    than C++), and (b) to trim irrelevant quoted text when you post
    a followup.

    --
    Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
    void Void(void) { Void(); } /* The recursive call of the void */

    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Lane W@3:633/10 to All on Tue Sep 8 19:24:50 2026
    Keith Thompson wrote:
    Lane W <cactus_DAC@yahoo.com> writes:
    Keith Thompson wrote:
    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.

    Well aren't you a fancy ancy.

    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.

    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?

    I'm done defending myself. It's clear you run a little cesspool here
    where I'm not going to get any back up for doing the right thing.

    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From fir@3:633/10 to All on Wed Sep 9 03:25:08 2026
    Lane W pisze:
    Keith Thompson wrote:

    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.

    Well aren't you a fancy ancy.

    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.

    in my opinion you can talk on c# bt just not very big amount preferebly

    it is matter of opinion : user keith thompson i guess think it should be
    100% C 0% offtopics, i think it preferably should be 90% C here but 5%
    of offtopics is not much a problem, but those spamers we got back them
    (rick hodgin , ramine, olcot and so on was terrible)

    so if you want tell me: which language solution in c# you find such
    good? (i used c# like few months 20 years ago and my memory on this
    language was its bad..i distacte OOP tremendously, also dont like
    bad times with all that terrible apis for xml and things like that,
    its just terrible)

    C is still superior , esp old C

    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Waldek Hebisch@3:633/10 to All on Wed Sep 9 01:59:11 2026
    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.

    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.

    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.
    Database technology was supposed to mitigate space overhead
    related to having many small files. Appropriate editors
    were supposed to make such system convenient. AFAICS
    this supporting technology did not get popular, and most
    developers simply used files.

    --
    Waldek Hebisch

    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Keith Thompson@3:633/10 to All on Tue Sep 8 19:26:23 2026
    Lane W <cactus_DAC@yahoo.com> writes:
    Keith Thompson wrote:
    Lane W <cactus_DAC@yahoo.com> writes:
    Keith Thompson wrote:
    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.

    Well aren't you a fancy ancy.

    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.

    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?

    I didn't say I hadn't seen any relevant posts. I said I didn't
    recall seeing any relevant posts. That was a true statement at
    the time, but it was also an error on my part, as I've already
    acknowledged. You did make a relevant post. I didn't remember it.

    Now that you've posted a followup, I do recall the post you're
    referring to. Here's the relevant part.

    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 see what you're trying to do. I dislike this code, though I didn't
    bother saying so at the time. The meaning of the variable "d"
    and the values 1, 2, and 3 are unclear. You unnecessarily assign
    values to d multiple times because use don't use "else". Yes,
    it demonstrates that there are multiple ways to do the same thing.
    Your way is not good. (And it has numerous syntax errors, though
    that's easy to fix.)

    It would be improved by using an enum rather than the meaningless values
    1, 2, and 3, though I still dislike the addition of a second layer of complexity.

    To be clear, my opinion of your code has nothing to do with the fact
    that you wrote it.

    I suggest that something like this would be much clearer:

    if (dodge < 0.5) {
    slog("%s easily dodged attack...", being[k].name);
    return 1;
    }
    else if (dodge < 0.9) {
    slog("%s hardly dodged attack...", being[k].name);
    return 1;
    }
    else if (dodge < 1.0) {
    slog("%s dodged attack...", being[k].name);
    return 1;
    }

    Or I might even write it like this:

    const char *const dodged =
    dodge < 0.5 ? "easily dodged" :
    dodge < 0.9 ? "hardly dodged" :
    dodge < 1.0 ? "dodged" : NULL;
    if (dodged) {
    slog("%s %s attack...", being[k].name, dodged);
    }

    --
    Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
    void Void(void) { Void(); } /* The recursive call of the void */

    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Janis Papanagnou@3:633/10 to All on Wed Sep 9 08:51:19 2026
    On 2026-09-08 17:45, Lane W wrote:
    [...]

    I don't understand why it's okay to talk about C++ here but not C#? C#
    is way better than C++.

    I think it's okay if there's an argumentative relation or comparison
    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.

    Janis


    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Janis Papanagnou@3:633/10 to All on Wed Sep 9 09:02:47 2026
    On 2026-09-09 02:02, Lane W wrote:
    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.

    No, unfortunately and obviously you didn't understand it. I'd say
    you missed to solve Keith's exercise, despite there had been even
    auxiliary information in David's post that could have helped you
    here understanding the point. (Hint: Is "A is "better" than B" a
    [true/false] information, or a personal [non-backed-up] opinion?)

    (And it's still irrelevant here in CLC to compare A with B whether
    in an opinion-based or in a substantial form.)

    Janis


    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Janis Papanagnou@3:633/10 to All on Wed Sep 9 09:13:34 2026
    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*)

    Janis just said he didn't
    like it. You've gone so far as to say it was not relevant.

    [...]


    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Johann 'Myrkraverk' Oskarsson@3:633/10 to All on Wed Sep 9 15:24:38 2026
    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#!
    --
    Johann | email: invalid -> com | http://www.myrkraverk.com/blog/
    I'm not from the Internet, I just work there. | via Easynews.com https://bsky.app/profile/myrkraverk.bsky.social | for ( ;; ) _:;

    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Janis Papanagnou@3:633/10 to All on Wed Sep 9 09:35:30 2026
    On 2026-09-08 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:

    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. [...]

    I second that. - At least in our very huge C++ projects back then the
    repeated and cascaded inclusion (with fibonacci call-characteristics)
    was a build-performance killer. That was the reason we introduced the
    #ifndef in the first place. - If the dependencies weren't in cascaded
    form I might be less concerned with modern machines, but as it is...

    Janis


    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Janis Papanagnou@3:633/10 to All on Wed Sep 9 09:59:03 2026
    On 2026-09-08 09:25, David Brown wrote:
    On 08/09/2026 00: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.)

    It is almost universal practice to have such include guards in header
    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.

    Janis


    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Janis Papanagnou@3:633/10 to All on Wed Sep 9 10:13:08 2026
    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).

    Janis


    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From David Brown@3:633/10 to All on Wed Sep 9 10:18:31 2026
    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.

    2. A "modern machine", in my mind, has multiple cores, plenty of ram,
    and a fast disk (good M2 SSD). If you are programming for a living, a
    machine that fits your uses is important.

    3. "Modern machine" implies, to some people, a "modern OS" suitable for
    the task. That means *nix, most likely Linux. There is no doubt that
    Linux is far better at dealing with large numbers of files at a time,
    such as big include sets, and far more efficient for handling the large
    number of processes used when doing big gcc builds. The gcc
    architecture is a fit for the strengths of *nix systems - it assumes
    that files are cached and fast to re-use, that splitting things into
    many small processes is efficient, and so on. (For comparison, MSVC is designed to play to Windows strengths - it holds much more in its own
    memory rather than OS file caches, and works as a monolithic
    multi-threaded program.)

    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 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).


    I understand your desire to speed up compilations, because compilation
    speed is important to you. (Why SDL matters to you is another
    question.) But you should also understand that many other people have different, more general ways to make build speed a minor issue (at least
    for C programs). If I can make build speed a non-issue for my work by
    using a decent PC, using Linux, using make, then that is something I can
    apply to /all/ my programs. 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 current
    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.





    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From fir@3:633/10 to All on Wed Sep 9 10:18:22 2026
    Johann 'Myrkraverk' Oskarsson pisze:
    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





    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Janis Papanagnou@3:633/10 to All on Wed Sep 9 10:26:47 2026
    On 2026-09-09 03:59, Waldek Hebisch wrote:
    [...]

    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.


    Please bear with me that I quote this part from the longish
    post; I think these contents should not be missed in the lot
    and emphasized.

    Janis

    [...]


    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From David Brown@3:633/10 to All on Wed Sep 9 10:35:52 2026
    On 09/09/2026 09:59, Janis Papanagnou wrote:
    On 2026-09-08 09:25, David Brown wrote:
    On 08/09/2026 00: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.)

    It is almost universal practice to have such include guards in header
    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.)


    There's no doubt that the C and C++ (prior to modules in C++20) headers
    are quite a primitive, low-level mechanism. They are very flexible, and
    can be used for much more than a clear, rigid module system - but with
    that flexibility to do weird and wonderful things comes the flexibility
    to do strange, confusing, inefficient or simple incorrect things. The
    same principle applies to the text-based macros of the C pre-processor.
    It requires discipline and convention to use well.

    And that flexibility also leads to disadvantages when trying to change
    or improve things - any new solution still has to work with code that
    includes the same file multiple times intentionally (such as for
    so-called "x-macros"), or has headers whose functionality depends on
    macro definitions before inclusion, and so on.

    Basically, if you are making a new language, you should include some
    kind of module system that is better than C has - but it is impractical
    to try to change C now. (Maybe C could later copy modules from C++,
    once there has been enough practical experience built up around them.
    But it would first have to copy namespaces.)


    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.)


    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.


    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.


    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.


    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.


    Agreed.

    (Of course that applies to a lot of aspects of C. It's a language that requires more programmer responsibility than some other languages where
    the tools can do more checks at compile-time, or you have more checks at run-time.)


    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From David Brown@3:633/10 to All on Wed Sep 9 10:38:02 2026
    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.)


    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Janis Papanagnou@3:633/10 to All on Wed Sep 9 11:35:10 2026
    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

    [...]


    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Janis Papanagnou@3:633/10 to All on Wed Sep 9 11:40:31 2026
    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


    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Keith Thompson@3:633/10 to All on Wed Sep 9 02:45:45 2026
    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.

    [...]

    --
    Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
    void Void(void) { Void(); } /* The recursive call of the void */

    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From fir@3:633/10 to All on Wed Sep 9 12:05:21 2026
    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)










    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From bart@3:633/10 to All on Wed Sep 9 12:32:10 2026
    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>


    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.

    Actually I chose SDL because it was a substantial library that was still fairly small and compact! SDL3 has grown somewhat from SDL2 but this is
    a comparison with GTK2 (for a C program that includes only SDL.h or GTK.h):
    SDL3 GTK2 (approx figures)

    No of unique headers 86 550
    Line count 82 Kloc 330 Kloc across unique headers
    Total #includes 346 1100
    Folders 1 12 at least

    The latest GTK is GTK4; no doubt that is bigger.

    My experiments in reducing each to a compact one-file representation
    suggested these would be the C header sizes that would result:

    SDL2 GTK2
    Number of files 1 1
    Line count 3 Kloc 25 Kloc (3Kloc reduced from 50Kloc)
    Total #includes 1 1

    (Based on converting SDL2/GTK2 headers files to sets of bindings in my language. In that language, the file would be processed exactly once per build; in C it would still be per module that includes the header.)


    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).

    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!

    Take some library whose source uses dozens of headers scattered over a multiple nested folders, full of conditional blocks for half a dozen
    different platforms.

    Say that library is made available as a shared binary, one DLL file on Windows. That makes sense (or even one .a file). The DLL will export (if
    you look inside) a linear set of functions and variables.

    But to use the library from C, you will need to process all those dozens
    of headers still, even though the developers' organisational choices are completely irrelevant to us.

    Wouldn't it be better, since they have already produced the one-file DLL
    file for out platform, to have a compact one-file header too?

    (I also had an idea to embed the header inside the DLL, that a compiler
    could extract, but that would need too much cooperation.)
    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.

    One-header libraries are popular, making them very easy to deploy.

    Although usually they will contain the implementation too.

    I did a brief check of the most include-heavy file in my current
    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.
    Yes, these are all techniques that can be used to mitigate what remains,
    at heart, a slow compiler.

    This seems of more priority than increasing raw compilation speeds.

    But it you are processing 3.6Mloc in 0.1 seconds, then that's 36Mlps of parsing speed, which is impressive for a big compiler, and therefore
    suspect! Even if most of it is comments or skipped conditional code.

    On my machine TCC processes the 82Kloc of SDL2 at only some 1.6Mlps.
    Although I don't know how many of those are re-processed due to repeated includes, even if that is skipping code between include guards.

    However, I doubt it will be anywhere near the speed of your compiler.

    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Johann 'Myrkraverk' Oskarsson@3:633/10 to All on Wed Sep 9 20:16:56 2026
    On 09/09/2026 4:18 PM, fir wrote:
    Johann 'Myrkraverk' Oskarsson pisze:
    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
    Yeah, I don't worry about Keith and trolls like him, and discuss what I
    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 | email: invalid -> com | http://www.myrkraverk.com/blog/
    I'm not from the Internet, I just work there. | via Easynews.com https://bsky.app/profile/myrkraverk.bsky.social | for ( ;; ) _:;

    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From David Brown@3:633/10 to All on Wed Sep 9 14:30:02 2026
    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
    sys 0m2.206s

    Compiling these 50 files on my system, in a sensible way, is about 40
    times faster than yours. My cpu has 6 real cores at 5 GHz, and 8
    low-power cores that might help a bit. I can believe it is inherently
    faster than your PC, but not 40 times faster.


    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.

    Other than occasional nonsense tests like this one, I rarely do native compilation. It's all cross-compilation for bare-metal embedded targets.


    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!


    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.



    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From fir@3:633/10 to All on Wed Sep 9 14:31:41 2026
    Johann 'Myrkraverk' Oskarsson pisze:
    On 09/09/2026 4:18 PM, fir wrote:
    Johann 'Myrkraverk' Oskarsson pisze:
    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
    Yeah, I don't worry about Keith and trolls like him, and discuss what I
    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


    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From fir@3:633/10 to All on Wed Sep 9 14:37:43 2026
    fir pisze:
    Johann 'Myrkraverk' Oskarsson pisze:
    On 09/09/2026 4:18 PM, fir wrote:
    Johann 'Myrkraverk' Oskarsson pisze:
    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
    Yeah, I don't worry about Keith and trolls like him, and discuss what I
    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

    besides he is partally right - he has a bit rigid definitions who troll
    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

    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From David Brown@3:633/10 to All on Wed Sep 9 14:43:35 2026
    On 09/09/2026 11:35, Janis Papanagnou wrote:
    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


    Just defining the symbol is fine - for use as a pure header guard, where
    the check is with "#ifndef" or "#ifdef", defining it to a value has no
    added value. Adding the "1" in that example was done without thinking.


    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Jan van den Broek@3:633/10 to All on Wed Sep 9 12:50:51 2026
    2026-09-09, Lane W <cactus_DAC@yahoo.com> schrieb:
    Keith Thompson wrote:

    [Schnipp]

    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 have the feeling that you're missing the point here (or you are
    just being ignorant).
    --
    Jan van den Broek
    balglaas@dds.nl 0xAFDAD00D
    http://huizen.dds.nl/~balglaas/

    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From David Brown@3:633/10 to All on Wed Sep 9 15:07:37 2026
    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.


    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Lane W@3:633/10 to All on Wed Sep 9 07:14:23 2026
    David Brown wrote:
    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.

    Agreed. Plus some C programmers use the switch keyword, which we 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.


    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From David Brown@3:633/10 to All on Wed Sep 9 15:31:31 2026
    On 09/09/2026 15:14, Lane W wrote:
    David Brown wrote:

    C's include system works well when used in a sensible and disciplined
    manner, but unfortunately not all C programmers are sensible and
    disciplined.

    Agreed. Plus some C programmers use the switch keyword, which we 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.)



    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Johann 'Myrkraverk' Oskarsson@3:633/10 to All on Wed Sep 9 21:37:52 2026
    On 09/09/2026 8:37 PM, fir wrote:
    fir pisze:
    Johann 'Myrkraverk' Oskarsson pisze:
    On 09/09/2026 4:18 PM, fir wrote:
    Johann 'Myrkraverk' Oskarsson pisze:
    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
    Yeah, I don't worry about Keith and trolls like him, and discuss what I
    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

    besides he is partally right - he has a bit rigid definitions who troll
    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

    Indeed. And for that reason, I still hope you'll read /Patterns in C/
    one of these days. Or if I -- or someone else -- comes across a better reference, to share it with you.

    There is a lot of C knowledge out there, and the language standard isn't
    the end game of being a C wizard.
    --
    Johann | email: invalid -> com | http://www.myrkraverk.com/blog/
    I'm not from the Internet, I just work there. | via Easynews.com https://bsky.app/profile/myrkraverk.bsky.social | for ( ;; ) _:;

    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Lane W@3:633/10 to All on Wed Sep 9 07:38:00 2026
    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.

    Janis just said he didn't like it. You've gone so far as to say it was
    not relevant.

    I think it's okay if there's an argumentative relation or comparison
    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.



    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Lane W@3:633/10 to All on Wed Sep 9 07:41:55 2026
    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 and disciplined
    manner, but unfortunately not all C programmers are sensible and
    disciplined.

    Agreed. Plus some C programmers use the switch keyword, which we 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.)


    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
    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?

    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From fir@3:633/10 to All on Wed Sep 9 15:58:04 2026
    Lane W pisze:
    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 and
    disciplined manner, but unfortunately not all C programmers are
    sensible and disciplined.

    Agreed. Plus some C programmers use the switch keyword, which we 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.)


    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
    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)

    what i wast talkin about was that (whot showed) there are
    cases in c programming ehen you need such construct


    if() {}
    if() {}
    if() {}
    if() {}
    othercase {}

    and c has no such thing in languuage

    you may add elses but then the logic of this laddes not fits the
    "intention" - becouse intention is 'i dont care for elses.. ifs are in intention liek independant..but i care of "othercase" case
    and c has no construction for it imo


    here as to this INTENTION the gotos would fit more than elses

    if() {} goto go_on;
    if() {} goto go_on;
    if() {} goto go_on;
    if() {} goto go_on;
    //othercase

    go_on:

    and switch also would be close to that but it not takes the d<0.3 type conditions/keys


    so conclusions were c lacks some language construct which i described as

    case() {}
    case() {}
    case() {}
    otherwise {}

    AND follow to that conclusion was that maybe C needs logical operator
    for ifs


    if() {} & if() {} | if() {} then {}

    thet was the core story her in my own intent ;c
    (some others talked about the snipets, its ok but i was writing on what
    i write here)

    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Lane W@3:633/10 to All on Wed Sep 9 08:05:30 2026
    fir wrote:
    Lane W pisze:
    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 and
    disciplined manner, but unfortunately not all C programmers are
    sensible and disciplined.

    Agreed. Plus some C programmers use the switch keyword, which we 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.)


    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 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?

    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From bart@3:633/10 to All on Wed Sep 9 15:09:13 2026
    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!

    Your approach is akin to buying a 250mph supercar to get from A to B via
    some long-winded, torturous route, when you can do it faster in a Model
    T by being more sensible.

    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From fir@3:633/10 to All on Wed Sep 9 16:10:01 2026
    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


    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From bart@3:633/10 to All on Wed Sep 9 15:11:46 2026
    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 and disciplined
    manner, but unfortunately not all C programmers are sensible and
    disciplined.

    Agreed. Plus some C programmers use the switch keyword, which we 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.



    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From fir@3:633/10 to All on Wed Sep 9 16:13:10 2026
    Lane W pisze:
    fir wrote:
    Lane W pisze:
    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 and
    disciplined manner, but unfortunately not all C programmers are
    sensible and disciplined.

    Agreed. Plus some C programmers use the switch keyword, which we
    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.)


    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 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?

    im not so uch sensitive on such kind of opinions i guess ;c
    for me here either something is interestin or no interesting and i make
    my own choices as to coding style (yawn)


    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Richard Harnden@3:633/10 to All on Wed Sep 9 15:16:31 2026
    On 09/09/2026 10:45, Keith Thompson wrote:
    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').

    Which header?

    I get that __anything, _Capital, E, str, mem and probably a few I've
    forgotten are reserved prefixes. I never heard of NUM or NUMBER being
    off limits. Seems a very common prefix that would get used a lot.



    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Johann "Myrkraverk" Oskarsson@3:633/10 to All on Wed Sep 9 22:16:53 2026
    On 9/9/2026 9:38 PM, Lane W wrote:
    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.

    Janis just said he didn't like it. You've gone so far as to say it
    was not relevant.

    I think it's okay if there's an argumentative relation or comparison
    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.



    But which of the plethora of fora? There is no comp.lang.csharp, as I
    harpened on in a different tangent to this discussion.

    And as I am not currently engaged in sharpening the C, I do not see a
    reason to harken in news.groups.proposals.


    Happy informal poetry in comp.lang.c!
    --
    Johann | email: invalid -> com | http://www.myrkraverk.com/blog/
    I'm not from the Internet, I just work there. | via Easynews.com https://bsky.app/profile/myrkraverk.bsky.social | for ( ;; ) _:;

    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From fir@3:633/10 to All on Wed Sep 9 16:19:18 2026
    fir pisze:
    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



    in fact hovever more thus subblocks could also execute..for me most interesting is conclusion thatthis seem the most natural syntax ofr switch

    case() { } case(){ } otherwise {}

    abstracting away form thise syntax details





    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Richard Harnden@3:633/10 to All on Wed Sep 9 15:23:43 2026
    On 09/09/2026 11:05, fir wrote:
    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

    ***************
    *
    ***************

    None of you proposed glyphs are easy to type - if they exist at all.

    People are used to "=" and "==", and I don't think there is an actual
    problem to be solved.

    I don't think anyone wants to go back to trigraphs.



    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)











    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Lane W@3:633/10 to All on Wed Sep 9 08:25:19 2026
    bart wrote:
    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 and
    disciplined manner, but unfortunately not all C programmers are
    sensible and disciplined.

    Agreed. Plus some C programmers use the switch keyword, which we 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.


    Here's a revision, where I take MORE THAN TEN SECONDS:

    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?

    WHERE ARE THESE SYNTAX ERRORS YOU NEVER EXPLICITLY STATE?

    Am I cleared for Heaven now?

    Can we get ten more people to hop on the bandwagon and RUDELY tell me
    how bad it is?

    I gauged that RUDENESS is something you try to avoid here.

    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From bart@3:633/10 to All on Wed Sep 9 15:53:38 2026
    On 09/09/2026 15:25, Lane W wrote:
    bart wrote:
    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 and
    disciplined manner, but unfortunately not all C programmers are
    sensible and disciplined.

    Agreed. Plus some C programmers use the switch keyword, which we 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.


    Here's a revision, where I take MORE THAN TEN SECONDS:

    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?
    You have 3 near-identical calls to slog(). And in this new version, 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.


    --------------------------------------------
    if(dodge <1.)
    {
    if(dodge < .5)
    { slog("%s easily dodged attack...", being[k].name); }
    else if(dodge > .9)
    { slog("%s hardly dodged attack...", being[k].name); }
    else
    slog("%s dodged attack...", being[k].name);

    return 1;
    }





    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From David Brown@3:633/10 to All on Wed Sep 9 16:58:01 2026
    On 09/09/2026 16:09, bart wrote:
    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?

    That's the sum of the time the cores spent, yes. This is more than the wall-clock time for a serial build, because there is some contention
    (shared memory caches and buses, for example), and hyper-threading and
    slower "low power" cores mean the parallel scaling is not linear.

    But I am not bothered about how much effort my computer has to do - the
    "real" time here is the wall-clock time that is vastly more relevant.



    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!

    When I am compiling my project, I am not particularly interested in how
    much time and effort by other people it took to have the tools. You
    don't consider it a big effort to sit down in your chair - you don't
    think about how much work it took to make the oil rig that drilled for
    the oil that was used to make the plastic that your chair is made from.
    I've got "make" and "gcc" on my computer. Using them here was one line.

    I'll admit that compiling all the s*.c files, then using "s*.o" as
    makefile targets could be called cheating - the files have to be there
    to be matched by the wildcard for re-building. So "make -j s*.o" would
    not work after a "rm s*.o". But I felt that a single-line solution to
    that would be a bit distracting, even though it still shows that no
    makefile was needed :

    ls s*.c | sed 's/c/o/g' | xargs make -j



    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.

    Imagine I already have these 10 machines that are each 5 times as fast.
    Should /I/ continue to do the tasks one at a time, using the old
    machine, just because /you/ think the old way is "more traditional" ?

    Imagine that I have already spent a few days (spread out over years)
    getting the hang of "make". Should I now not use it? Imagine I have
    already purchased a computer with more than one core. Should I stick to
    using just a single core? Should I throw away all my good tools, and
    instead choose some weak little compiler, piss-poor excuse for an OS,
    and a batch file for build control - and then moan that big header files
    make builds slow?


    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?

    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.
    Instead, I can take previously-written makefiles, adjust a bit to suit
    my current project, and I've got all I need.

    Now, if my job was working at a microcontroller manufacturer's
    development tool department, then I might consider how to arrange header
    files to improve built speeds - because lots of people could benefit.
    But in practice I would be far more interested in improving the code
    quality, clarity, organisation and re-usability than tiny speedups.


    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.)


    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%. It does not matter how long it takes to read
    the SDL3 headers and throw them away, because it is not a useful task.


    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!


    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.



    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From David Brown@3:633/10 to All on Wed Sep 9 17:02:55 2026
    On 09/09/2026 15:41, Lane W wrote:
    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 and
    disciplined manner, but unfortunately not all C programmers are
    sensible and disciplined.

    Agreed. Plus some C programmers use the switch keyword, which we 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.)


    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
    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?

    Nobody except you has described your code as "evil" or thinks morality
    has anything to do with it. People just didn't like your code example -
    they thought it was unnecessarily complex and a poor choice of structure.

    Oh, and the OP did not ask to avoid "if then else" - he wanted ideas of
    a different structure from the one he had.


    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Scott Lurndal@3:633/10 to All on Wed Sep 9 15:04:41 2026
    Lane W <cactus_DAC@yahoo.com> writes:
    bart wrote:
    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 and
    disciplined manner, but unfortunately not all C programmers are
    sensible and disciplined.

    Agreed. Plus some C programmers use the switch keyword, which we 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.


    Here's a revision, where I take MORE THAN TEN SECONDS:

    No need to shout.


    Can we get ten more people to hop on the bandwagon and RUDELY tell me
    how bad it is?

    <snip>

    I'll join the list. That's really bad code.


    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Scott Lurndal@3:633/10 to All on Wed Sep 9 15:10:38 2026
    David Brown <david.brown@hesbynett.no> writes:
    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.

    Indeed. Using a parallel make (-j 96), I can clone the repo
    and build it in only 8 minutes. A sequential make takes over
    three hours. Modifying and changing a single source file
    recompiles and links in few seconds (with a couple outliers, one that
    takes 6 minutes with -O3 vs. 15 seconds without optimization).

    <snip>


    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From David Brown@3:633/10 to All on Wed Sep 9 17:12:21 2026
    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.

    Your new code is less bad - the enumeration avoids the meaningless magic numbers. But it is not clear if you intend this to be separate
    functions (which could be a useful thing if the code section is reusable
    - only the OP can tell us if that's the case), or if it is intended to
    be combined inside one function. If it is is the later, that is
    unhelpful additional complexity as the code stands.

    You have fixed some of the syntax errors in the original code, but
    introduced new ones (hint - look at the definition of the enumeration
    type). You might find <https://godbolt.org> a useful tool here - it's
    an online compiler that makes it very easy to check the syntax of code.
    It's a site I use multiple times a day for a variety of purposes.



    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From fir@3:633/10 to All on Wed Sep 9 17:42:47 2026
    bart pisze:
    On 09/09/2026 15:25, Lane W wrote:
    bart wrote:
    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 and
    disciplined manner, but unfortunately not all C programmers are
    sensible and disciplined.

    Agreed. Plus some C programmers use the switch keyword, which we
    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.


    Here's a revision, where I take MORE THAN TEN SECONDS:

    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?
    You have 3 near-identical calls to slog(). And in this new version, 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;
    }


    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Scott Lurndal@3:633/10 to All on Wed Sep 9 15:48:55 2026
    bart <bc@freeuk.com> writes:
    On 09/09/2026 15:25, Lane W wrote:


    WHERE IS THIS DUPLICATION?
    You have 3 near-identical calls to slog(). And in this new version, 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";

    So you assign sdodge up to three times. A waste of cycles.

    Ugly code.

    Difficult to maintain.



    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From fir@3:633/10 to All on Wed Sep 9 17:53:30 2026
    fir pisze:
    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


    i see is should add the optimisation if(&slog_[i][0]) ....


    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;
    }







    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Johann "Myrkraverk" Oskarsson@3:633/10 to All on Wed Sep 9 23:59:16 2026
    On 9/9/2026 11:12 PM, David Brown wrote:
    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.

    You shouldn't call other people rude, David Brown, the brown, because
    you're always rude. You just don't understand it, because you're always
    rude.

    So to stop being rude, you'll have to stop posting on Usenet. Go away!
    --
    Johann | email: invalid -> com | http://www.myrkraverk.com/blog/
    I'm not from the Internet, I just work there. | via Easynews.com https://bsky.app/profile/myrkraverk.bsky.social | for ( ;; ) _:;

    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From fir@3:633/10 to All on Wed Sep 9 18:03:02 2026
    fir pisze:
    fir pisze:
    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


    i see is should add the optimisation˙˙ if(&slog_[i][0]) ....


    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,
    it also suggested using vsnprintf(&slog_[slog_top][0], slog_line_max,
    format, args); and turning &slog_[i][0] into slog[i]

    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From fir@3:633/10 to All on Wed Sep 9 18:19:24 2026
    fir pisze:
    fir pisze:
    fir pisze:
    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


    i see is should add the optimisation˙˙ if(&slog_[i][0]) ....


    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,
    it also suggested using˙ vsnprintf(&slog_[slog_top][0], slog_line_max, format, args); and turning˙ &slog_[i][0] into slog[i]


    should rather add

    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]) ;
    }

    forthsi optimisation

    i overally see that this slog_top winding is suelles
    (i wanted before to draw lastamount of messages but in mya game case
    it showed i more like reset _slog often and draw the portion from 0 to slog_top so its like not finished as i dont needed the standard console mode

    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From fir@3:633/10 to All on Wed Sep 9 18:49:59 2026
    here this memory console code in to wersion one is this reseting and one
    is this that rolls and displays last N messages,

    its curiosu how such code of suchlike console has only few lines 'machenically'


    const int slog_line_max = 250, slog_lines_max = 500;

    char slog_[slog_lines_max][slog_line_max];
    int slog_top = 0;


    void DrawSlog_LastOnes()
    {
    const int last_lines_to_display = 17;
    int beg = slog_top-last_lines_to_display;

    for(int i=0; i<last_lines_to_display; i++)
    {
    int line = beg+i;
    if(line<0) line+=slog_lines_max;

    if(slog_[line][0])
    text_xyc_helvetica(10, helvetica_size*(i+3),0xe8e8e0, slog_[line]) ;
    }
    }

    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]) ;
    }

    void ResetSlog() { slog_top = 0; }

    void slog(char *format, ...)
    {
    va_list args;
    va_start(args, format);
    vsnprintf(slog_[slog_top], slog_line_max, format, args);
    va_end(args);

    slog_top++;
    if(slog_top>=slog_lines_max) slog_top=0;
    }





    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From fir@3:633/10 to All on Wed Sep 9 19:16:44 2026
    fir pisze:
    bart pisze:
    On 09/09/2026 15:25, Lane W wrote:
    bart wrote:
    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 and
    disciplined manner, but unfortunately not all C programmers are >>>>>>> sensible and disciplined.

    Agreed. Plus some C programmers use the switch keyword, which we
    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.


    Here's a revision, where I take MORE THAN TEN SECONDS:

    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?
    You have 3 near-identical calls to slog(). And in this new version,
    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;
    ˙˙ }


    nota BTW some theoretical remark - related to thise "knots?webs?" post i
    wrote few days ago

    you may name such slog an object (or entity)

    its main function is
    1) slog(...) it also
    2) needs its data (included or initialised/created)
    3) it also has function draw
    4) it also has small function reset

    its all good but what is a problem - problem is you need to
    put especially this draw(0 and reset(0 calls in appropriate places in code

    so this is not (or not only) and object/entity its a WEB or its a KNOT
    and that is kinda problem


    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From bart@3:633/10 to All on Wed Sep 9 18:34:33 2026
    On 09/09/2026 15:58, David Brown wrote:
    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'm not saying that. But people SHOULD be more critical of how fast
    their tools are, instead of just throwing more brute force at the problem.

    Tiny C *does* seem to do the same task (parse huge amounts of
    declarations) at least a magnitude faster than TCC. TCC wouldn't need
    those extra cores. Maybe gcc wouldn't either.

    You see the same thing assemblers. There, there is no backend optimising
    of the kind that compilers do. Assembling is a simple, linear process.

    And yet, you can see 10:1 difference in assembling the same program.
    What on earth are those slow ones up to?

    ˙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.

    I'm not saying that either. I think people who supply the API headers
    should do that.


    TCC is, at best, a very niche tool.˙ It is not an alternative for
    serious development work.

    It provides one invaluable service: it shows just how slow some
    compilers are, even doing the same task.


    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.

    And yet, precompiled headers were introduced. Why, if it is a non-issue?



    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%.

    So it doesn't matter at all how large and bloated any library's headers are?

    This attitude is why we see bloat everywhere as well as some dead-slow applications. Maybe some people want to sell more RAM and more hardware; that's not going to happen if existing tools are too fast!

    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!


    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.
    Certainly, the line counts of big libraries are likely to dwarf that of
    many applications, and that's if you only count them once.

    But if an application has N modules that import those big headers, then
    they have to be processed N times.

    So yes I think it can be significant. GTK4 may well approach half a
    million lines now, and windows.h may be up to 200K lines.

    It doesn't bother you because you've found a way to work with slow
    compilers. That's fine; long ago *I* had to find a way to work with slow hardware.

    Here is a 4-line Hello program using Windows, mess.c:

    #include <windows.h>
    int main() {
    MessageBoxA(0, "caption", "hello", 0);
    }

    This is how it takes to build on my Windows PC:

    c:\c>tim tcc mess.c -luser32
    Time: 0.044

    c:\c>tim bcc mess
    Compiling mess.c to mess.exe
    Time: 0.035

    c:\c>tim gcc mess.c
    Time: 1.359

    1.3 seconds for a 4-line program!

    Since gcc takes 0.2 seconds even for a text hello.c, 1.1 seconds is
    spent processing windows.h.

    That is the reality for me and for lots of other people.


    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From bart@3:633/10 to All on Wed Sep 9 18:38:07 2026
    On 09/09/2026 16:48, Scott Lurndal wrote:
    bart <bc@freeuk.com> writes:
    On 09/09/2026 15:25, Lane W wrote:


    WHERE IS THIS DUPLICATION?
    You have 3 near-identical calls to slog(). And in this new version, 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";

    So you assign sdodge up to three times. A waste of cycles.

    This was adapted from Lane W's code. I was addressing the duplicated
    slog calls and the poor choice of enums.



    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From bart@3:633/10 to All on Wed Sep 9 19:12:44 2026
    On 09/09/2026 02:59, Waldek Hebisch wrote:
    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.

    People around here always seems to be making excuses for C!

    I find that adding include files, creating headers, maintaining forward declarations etc to be a complete PITA.

    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.

    Some even specify individual names to be imported from a module. What a complete waste of time!

    It's bad enough listing the modules themselves, of which there may a
    dozen or two, but there could be hundreds of imported functions.

    A module scheme should mean less work not more.



    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.

    According to David Brown and Scott Lurndal, that is a non-problem!

    And according to DB, reducing a large, complex mass of header files (of external library) into one compact file 95% smaller, would be a waste of
    time.

    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.

    I tried a scheme in C once. That is, a scheme where you submitted only
    the main.c file to the compiler, then it discovered the rest.

    It worked well, but required programs to be written in a certain way.
    For example, each module file.c required a matching file.h header.

    In the main module, you only included the .h files needed by this
    module. It would then add those .c files, and applied the process
    recursively.

    However all the projects I wanted to build weren't structured like this.


    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.

    With separate interface files, who writes the interface: is it the
    programmer who has to duplicate what is in the implementation? (In which
    case, what checks are made that it matches?)

    Or is it automatic?

    My first attempts at (modern) modules tried to do the latter, but it was
    hard. For example, compile module A.m and it generates A.exp which is
    the interface that can be used elsewhere via 'import A'.

    But suppose A and B import each other; which is compiled first?

    This is an advantage of a manually written interface, in that cyclic
    imports become easier, and you don't need a heirarchical structure.


    IIUC modules with separate iterface and implementation were
    advocated together with database-like storage of source code.

    I now work with whole program compilers. There, a discrete interface
    file doesn't make sense and is not needed between the modules of the
    same program.

    But they still exist at the boundaries of the program: when the program imports an external library, or my program is a library that exports functions. In that case, they are only partly automated.



    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)