• Re: Official list of top C annoyances

    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)
  • From Scott Lurndal@3:633/10 to All on Wed Sep 9 18:37:23 2026
    bart <bc@freeuk.com> writes:
    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.

    That is a strawman argument. You assume that a 50 millisecond difference
    in execution time is a critical issue that must be addressed, when in
    fact, the traditional unix tools are fast, elegent and efficient. You
    don't like them, fine. Don't claim that everyone else should agree
    with you.

    The days of submitting a deck of cards and waiting 24 hours for your
    output are long gone.


    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.

    Neither TCC nor Tiny C can compile my code successfully. Nor would I trust them
    to generate production quality code.

    <snip>


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

    We've been surreptitiously adding special code to the assembler that recognizes when Bart is running it so it can randomly add a bunch of
    spurious sleep(3) calls just to piss you off.


    ˙I am not interested in spending days or weeks

    Then don't. Nobody else thinks that the size and organization
    of these header files are out of the ordinary or in any way
    defective.

    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.

    Just to make you happy? It wouldn't work, you'd just find something
    else to complain about.



    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.

    No, they're not "doing the same task". TCC will not compile
    my code successfully. gcc and clang will.



    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?

    Because someone like you pushed for them. I'm not aware of anyone
    that actually uses precompiled headers.

    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From tTh@3:633/10 to All on Wed Sep 9 21:01:34 2026
    On 9/9/26 20:12, bart wrote:

    A module scheme should mean less work not more.

    So, just use Modern Fortran.

    --
    ** **
    * tTh des Bourtoulots *
    * http://maison.tth.netlib.re/ *
    ** **

    --- 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 20:12:26 2026
    On 09/09/2026 19:37, Scott Lurndal wrote:
    bart <bc@freeuk.com> writes:

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

    Just to make you happy? It wouldn't work, you'd just find something
    else to complain about.

    No, to do it Right. There is no need to expose all the machinery and
    innards of a developer's header files; users just need a flat API.

    If they include SDK.h, why exactly does it need to be 86 files rather
    than one? The whole thing will need processing in either case.



    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.

    No, they're not "doing the same task". TCC will not compile
    my code successfully. gcc and clang will.

    You're ignoring the point: it shows that 4 million lines of headers can
    be parsed 20 times faster gcc. There is little executable code here.




    --- 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 21:39:52 2026
    On 09/09/2026 19:34, bart wrote:
    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.


    That could make sense if there was a wide selection of tools to choose
    from. The options in my line of work are gcc, clang (which is not as
    mature in the field, and not significantly faster to use), or one of a
    few very expensive commercial toolchains that are not faster to use,
    have fewer features, are significantly behind the times in standards
    support, are often slower to fix bugs, and much less practical due to unpleasant security locks. (They can sometimes be useful for providing arse-coverage in court cases, however - "The bugs that lead to your car crashing are not our fault - we used the most expensive tools available".)

    The simple fact is that good quality C compilers, with good static
    analysis, good error messages, solid optimisations, standards support,
    and useful (for many uses, essential) extensions need to do a lot of
    work. That takes time.

    There is always scope for making tools a bit faster, at least. And that happens to some extent. Competition from the newbie clang/llvm lead to
    gcc putting a little more effort into speed of compilation, and a lot
    more effort into the quality of warning messages (especially in C++), as people saw that clang did better there. Then as clang got stronger optimisations and error analysis to compete with gcc, it slowed down -
    now they have a fair degree of similarity.

    Compiler developers have limited time and resources, just like everyone
    else. When they are prioritising tool speed, they do so where it
    matters most - the link-time optimisation. The speed of simple C
    compilation is fast enough that it usually doesn't matter, so they
    priorities better static analysis, better code generation, support for
    newer standards, bug fixes - things that really matter to users.

    Sure, I'd be happier if gcc were faster. But it's not in my top twenty
    list of things I'd like to see improved in the toolchain. I've
    occasionally filed bugs / issues with suggestions, and at least once had
    my suggestion directly used to improve the toolchain (IMHO, of course) - simply filing a request "make the compiler faster" is unlikely to be considered helpful.

    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?


    It's not hard to make programs that are slow for a particular task.
    Once you have reached a certain point, however, it's far harder to make
    them much faster. I believe there was a mainstream assembler that had a particularly poor algorithm somewhere, resulting in surprisingly long
    run times once input was over a certain size. I don't imagine it is a
    general problem, however.

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


    Again, I'd be happy with that - but again, it would not make my
    top-twenty list of things I'd rather the spend time on if they want to
    make a better SDK.


    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.


    I don't know how often it needs repeating - tcc is not doing the same
    job as gcc (or clang, or MSVC, or other serious compilers). That's not
    an insult to the tool or its developers, it's just a different tool with
    very different priorities.


    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?


    They are primarily for C++, not C. Reading in big C++ headers is a
    totally different scale of operation from reading C headers of the same
    line count.



    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?


    Again - I would always be happier if they were smaller or better
    organised. Of course I would prefer a 15% speedup if it were freely
    available without reduction of functionality or features. But it is not
    a matter that concerns me. I'd rather see effort put into improving the quality (in various aspects) of headers I need to use than.

    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!

    You still don't understand. No one is looking for "bloat" or slow
    tools. But once something is fast enough for what you want, making it
    faster or smaller should not be a major priority. If I felt I spent a
    lot of time waiting for my builds, I would want them to be faster - but
    I don't have to wait for them. There are plenty of other things I'd
    rather get annoyed about instead.



    --- 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 21:45:13 2026
    On 09/09/2026 20:12, bart wrote:

    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.
    Please stop paraphrasing me (and other people) incorrectly. Instead,
    just assume that you have misunderstood what people have said, and
    continue discussing them in the relevant thread in the hope that you eventually understand it. I am happy to discuss many things with you,
    but I find your repeated misquoting extremely frustrating.




    --- 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 22:11:49 2026
    On 2026-09-09 20:37, Scott Lurndal wrote:
    bart <bc@freeuk.com> writes:

    The days of submitting a deck of cards and waiting 24 hours for your
    output are long gone.

    Hey, where have you been working? - We regularly waited less than 1
    hour to get the output from our card decks! - Upgrade your systems
    or employ more admins. ;-}

    [...]

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

    Because someone like you pushed for them. I'm not aware of anyone
    that actually uses precompiled headers.

    I have to admit that my memories are faint here, but I seem to recall
    that we took advantage from precompiled headers.

    And, sadly, I cannot tell whether it were "someone [like you]" (the
    customers) that "pushed" the demand or whether the vendors recognized
    that feature (whether by customer feedback or by own investigation).

    (If you have some substantial evidence about that I'd like to hear.)

    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 Wed Sep 9 21:18:26 2026
    On 09/09/2026 20:45, David Brown wrote:
    On 09/09/2026 20:12, bart wrote:

    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.
    Please stop paraphrasing me (and other people) incorrectly.˙ Instead,
    just assume that you have misunderstood what people have said, and
    continue discussing them in the relevant thread in the hope that you eventually understand it.˙ I am happy to discuss many things with you,
    but I find your repeated misquoting extremely frustrating.
    You said this:

    As I showed in my timings, in real use, that [reducing headers by 95%] 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.

    In an earlier post (09:18 BST today) you said:

    Trying to optimise or flatten header sets for some library would be
    a waste of effort - the effect is too minor.

    Both sound very much as though consider it a waste of time.


    You are also ignoring a simple fact: how large is a typical source file
    size in C; 1000 lines maybe?

    Well each .c file that includes SDK.h needs to first process 82,000
    /unique/ lines of source, before getting around to those 1000 lines.

    But that's also ignoring that a lot more than 82Kloc needs to be either processed or skipped since many are re-included: there are 466
    #includes! In fact here are the figures from my compiler:

    Total lines processed: 551,674

    Of those, 150,000 are conditional false blocks that skipped over, but it
    still leaves 400,000 lines.

    This is 400Kloc for a ONE module of 1Kloc, and there could be other
    modules pulling in the same header. So, I would say that is quite
    dominant, for a non-optimising build.


    --- 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 21:39:14 2026
    On 09/09/2026 20:39, David Brown wrote:
    On 09/09/2026 19:34, bart wrote:

    You see the same thing [with] 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?


    It's not hard to make programs that are slow for a particular task. Once
    you have reached a certain point, however, it's far harder to make them
    much faster.˙ I believe there was a mainstream assembler that had a particularly poor algorithm somewhere, resulting in surprisingly long
    run times once input was over a certain size.˙ I don't imagine it is a general problem, however.

    NASM, MASM, or both?

    I know there is a long standing bug in NASM which leads to result like
    these, for this 270Kloc input (actually, an SQL test compiled into three different x64 ASM formats):

    nasm -O0 -fwin64 250 seconds (to .obj)
    yasm -fwin64 1.06 seconds (to .obj)
    as 0.65 seconds (to .o)
    aa 0.10 seconds (to .exe)

    Obviously, 'aa' is my product. And clearly, NASM has something wrong.
    (Without -O0, it would be 60% slower!)

    MASM (as 'ml64.exe') had its own bug to do with using RESB in a .DATA
    segment; it got exponentially slower with the size of the block. (I no
    longer have it to test.)

    For whole-program compilers that generate a single ASM file, assembly
    speed is critical.


    --- 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 23:07:37 2026
    On 2026-09-09 16:23, Richard Harnden wrote:
    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:

    [ Below post is completely unrelated to what had been quoted here
    so I'm snipping all of it ]



    note this pascal sign := is not stupid in some way but it has
    disadvanteges - whose in best approach should be none

    (No one yet said, suggested, or implied that symbol being "stupid".)


    := 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

    I consider "worse looking" as an expression of your personal opinion;
    as opposed to a fact-based real and commonly accepted disadvantage.

    (Personally I think that '=;' is an extremely bad proposal for that
    purpose. On a green field, my own preference would probably be some
    sort of arrow as assignment operator, say '<-', '->', or even ? or ?
    (*if* it would be easily usable in various technical environments).
    But I'm also completely fine with ':=' (or ':-' for REFs in Simula).
    And luckily I can also "master" C's '=' for that purpose easily, or
    even program in many different languages in parallel that support all
    sorts of variants for assignments and comparison operators.)

    := ADV 2) it has sense of direction (compared to =)

    Yes, I think that indicating a direction can be advantageous (to the uninitiated, at least).

    := DIS 3) it has only left right sense of direcion - and preferably it
    should have jet up down (so 4 possible versions)

    (I don't know what's going on in your brain to ask for "4 versions".)

    Common language designs have typically defined one direction, and this
    is sufficient. - Most(?) languages seem to have a <target> <- <source> convention but there's also languages with <source> -> <target> syntax.
    I wouldn't mind; I can use the convention of the languages I use with
    no problem.


    = 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

    Yes, that's a long and well-known disadvantage of '=' for assignments.


    it maybe come form basiclike

    (It predates BASIC.)

    But there need not be a problem using '=' for assignments and also
    for comparisons if the respective languages could tell them apart by
    context and with appropriate semantic rules.


    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

    (Please, for the sake of the people that haven't killfiled you, use an online-translator to create comprehensible texts! - In case that your
    native language *is* English I suggest to translate your text to some
    other language and then back to English; the translators are obviously
    good enough to fix your language or writing problems in that process.)

    Janis

    [...]


    --- 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 21:15:12 2026
    Janis Papanagnou <janis_papanagnou+ng@hotmail.com> writes:
    On 2026-09-09 20:37, Scott Lurndal wrote:
    bart <bc@freeuk.com> writes:

    The days of submitting a deck of cards and waiting 24 hours for your
    output are long gone.

    Hey, where have you been working? - We regularly waited less than 1
    hour to get the output from our card decks! - Upgrade your systems
    or employ more admins. ;-}

    [...]

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

    Because someone like you pushed for them. I'm not aware of anyone
    that actually uses precompiled headers.

    I have to admit that my memories are faint here, but I seem to recall
    that we took advantage from precompiled headers.

    And, sadly, I cannot tell whether it were "someone [like you]" (the >customers) that "pushed" the demand or whether the vendors recognized
    that feature (whether by customer feedback or by own investigation).

    (If you have some substantial evidence about that I'd like to hear.)

    It does appear to be used by MSVC somewhat automatically, but it's been
    three decades since I wrote any Windows code (and it was driver code for
    NT 3.51).

    Other restrictions on the GCC implementation include:

    Include order matters: The PCH must be the absolute first token the
    compiler encounters. You cannot put any code, variable declarations,
    or macro defines before it.

    One per compilation: Only one precompiled header can be used in a particular
    compilation.

    Identical flags: The .gch file must be built using the exact same flags
    (e.g., -O3, -g, -std=c++20, -m64) as the source files using it.

    Matching compiler binary: You must use the exact same compiler version to
    build the PCH and the final executable

    --- 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 23:26:02 2026
    On 2026-09-09 20:12, bart wrote:
    On 09/09/2026 02:59, Waldek Hebisch wrote:
    [...]

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

    I fear you're just exposing your very limited perception and experience
    here. (And en passant probably also the mindset of a technocratic paper
    pusher than a software designer.)

    Myself I'm favoring _to be able_ to import only what I need and not the
    whole bunch of existing things of a module (with all potential implicit
    and explicit consequences).

    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 23:37:48 2026
    On 2026-09-09 23:15, Scott Lurndal wrote:
    Janis Papanagnou <janis_papanagnou+ng@hotmail.com> writes:
    On 2026-09-09 20:37, Scott Lurndal wrote:
    bart <bc@freeuk.com> writes:

    The days of submitting a deck of cards and waiting 24 hours for your
    output are long gone.

    Hey, where have you been working? - We regularly waited less than 1
    hour to get the output from our card decks! - Upgrade your systems
    or employ more admins. ;-}

    [...]

    And yet, precompiled headers were introduced. Why, if it is a non-issue? >>>
    Because someone like you pushed for them. I'm not aware of anyone
    that actually uses precompiled headers.

    I have to admit that my memories are faint here, but I seem to recall
    that we took advantage from precompiled headers.

    And, sadly, I cannot tell whether it were "someone [like you]" (the
    customers) that "pushed" the demand or whether the vendors recognized
    that feature (whether by customer feedback or by own investigation).

    (If you have some substantial evidence about that I'd like to hear.)

    It does appear to be used by MSVC somewhat automatically, but it's been
    three decades since I wrote any Windows code (and it was driver code for
    NT 3.51).

    Other restrictions on the GCC implementation include:

    Include order matters: The PCH must be the absolute first token the
    compiler encounters. You cannot put any code, variable declarations,
    or macro defines before it.

    One per compilation: Only one precompiled header can be used in a particular
    compilation.

    Identical flags: The .gch file must be built using the exact same flags
    (e.g., -O3, -g, -std=c++20, -m64) as the source files using it.

    Matching compiler binary: You must use the exact same compiler version to
    build the PCH and the final executable

    Our usages were back in the 1990's on commercial Unix systems. The
    precompiled headers feature was (in our C++ context) just there, but
    not per default, it needed some option (or so) to make use of them.
    I don't recall any organizational restrictions with their use.

    They were obviously considered worthwhile (or even necessary) by the
    vendors to be provided for their customers for performance reasons
    in projects of non-trivial size.

    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 14:41:55 2026
    bart <bc@freeuk.com> writes:
    [...]
    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.
    [...]

    Aren't Tiny C and TCC the same thing? Did you mean "at least a
    magnitude faster than gcc"?

    --
    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 Keith Thompson@3:633/10 to All on Wed Sep 9 15:13:08 2026
    Lane W <cactus_DAC@yahoo.com> writes:
    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?

    No, of course not.

    David Brown already covered most of the points I was going to make,
    and I agree with what he wrote in this subthread.

    I initially ignored your code because it was in a thread I wasn't
    particularly interested in. I later decided to review it because
    it was brought to my attention.

    If you think I dislike the switch statement, you've reached a
    completely incorrect and unjustified conclusion.

    I dislike the particular code snippet that you posted, code
    that happened to use a switch statement (inappropriately IMHO).
    There are plenty of valid uses for switch statements, and I don't
    hesitate to use it when it's appropriate. It seemed to me that you artificially added a layer of complexity so you could use a switch
    statement rather than an if/else chain -- and to set that up, you
    used a sequence of if statements (with no "else" for some reason).

    My criticism of your code has nothing to do with the fact that you
    wrote it. To be blunt, I don't care enough about you personally to
    go out of my way to nitpick your code. I would have had similar
    criticisms if the code had been posted by the late Dennis Ritchie
    or by Brian Kernighan, though I would have been more reticent in
    expressing my opinions.

    The idea behind your code is not necessarily a bad one.
    You transformed a floating-point input value partitioned into
    ranges into a discrete value, with one discrete value corresponding
    to each range. That can be a useful technique. For one thing,
    it's an opportunity to give a meaningful name to each input range
    (but you just used 1, 2, 3). In some cases, it might allow fewer floating-point operations to be performed before making a decision,
    which could be significant in performance-critical code.

    But your specific code in this specific case was not good.
    Leaving out the extra transformation step would, in this case,
    make the code clearer and more efficient.

    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.

    Dude, get over yourself. Pretending to be persecuted because someone criticized your code is not a good look.

    --
    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 Keith Thompson@3:633/10 to All on Wed Sep 9 15:30:28 2026
    Lane W <cactus_DAC@yahoo.com> writes:
    [...]
    enum Dodges {
    NEAT : 1
    FLAWED : 2
    BARELY : 3
    UNSUCCESS : 4
    };

    I strongly suggest you try compiling any code that you're going to post
    here. This is not the correct syntax for an enum type. I presume
    you're trying to specify values for NEAT, FLAWED, et al, but I see no
    reason not to just rely on the default values of 0, 1, ....

    Unlike your initial code snippet, you're giving names to the cases
    rather than just using constants 1, 2, 3, which is an improvement.

    enum Dodges d = UNSUCCESS;

    if (dodge < 1)
    d = BARELY;
    if (dodge < 0.9)
    d = FLAWED;
    if (dodge < 0.5)
    d = NEAT;

    As I recall (I might be mistaken), your original code ignored
    the possibility that dodge could be >= 1. (For consistency, I'd
    definitely write 1.0 rather than 1 here).

    If dodge < 0.5, you test its value 3 times and update the value of d
    3 times. The performance impact is trivial, but it's conceptually
    more complex than it needs to be. I'd put the (dodge < 0.5) test
    first and use an else-if chain. (The fact that this forces the
    order of the tests is mildly annoying, I suppose.)

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

    The association between NEAT and "easily", FLAWED and "hardly", and
    BARELY and nothing, seems arbitrary. I'd probably give the enumeration constants names that match the string.

    WHERE IS THIS DUPLICATION?

    WHERE ARE THESE SYNTAX ERRORS YOU NEVER EXPLICITLY STATE?

    I don't know whether there were syntax errors in your previous code.
    If the syntax errors in your new code were corrected, this might
    be a decent demonstration of a useful technique: transforming a
    range of floating-point values into discrete values so they can be
    operated on more easily. In this particular case, I wouldn't bother.
    There are only 3 normal and 1 exceptional cases being considered, and
    I personally would prefer to test the floating-point value directly.
    If I want to assign names to the ranges, the strings passed to slog()
    express that clearly enough, or I might add comments.

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

    In a more complicated case, setting up the enum values could be a
    good idea, particularly if those values are going to be used later
    in the code. If this is a simple example meant to demonstrate the
    technique, that's fine. There's a big difference between writing
    code to demonstrate a concept (which often needs to be simplified)
    and writing real-world code.

    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.

    *yawn*

    --
    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 bart@3:633/10 to All on Wed Sep 9 23:30:49 2026
    On 09/09/2026 22:26, Janis Papanagnou wrote:
    On 2026-09-09 20:12, bart wrote:
    On 09/09/2026 02:59, Waldek Hebisch wrote:
    [...]

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

    I fear you're just exposing your very limited perception and experience
    here. (And en passant probably also the mindset of a technocratic paper pusher than a software designer.)

    Myself I'm favoring _to be able_ to import only what I need and not the
    whole bunch of existing things of a module (with all potential implicit
    and explicit consequences).
    Why? What is the advantage of so much micromanagement?

    Is even the pain of having to do '#include <string.h>' not enough when
    your code uses string functions, you would prefer to list them
    individually too?!

    With other languages, do you also need to specify importing individual variables, enumerations, types, structs and macros?

    An enumeration set may have hundreds of names; do you have to list all
    of them? That would be insane.

    I'd originally complained about having to list modules individually in
    in each file; this would be literally magnitudes worse.

    You might as well put each entity into its own module, and have a subset
    of 1000 modules to manage instead - in each of the 1000 functions.

    You people seem to like making life difficult. Well, go ahead!


    Myself I'm favoring _to be able_ to import only what I need and not the whole bunch of existing things of a module (with all potential implicit
    and explicit consequences).

    Which consequences are these? If there's too much unrelated stuff in a
    module, that suggests it is poorly structured.

    If you import modules A and B, and use functions from each, but some may
    clash (say you want F from A but not F from B), then that's not a
    problem because you will say A.F or B.F.

    If you want to use 'using' because you don't want to type 'A.' or 'B.',
    just F and it will be from a specific import, that /that/ would be bad
    form. In any case, there are better ways.


    --- 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 23:31:27 2026
    On 09/09/2026 22:41, Keith Thompson wrote:
    bart <bc@freeuk.com> writes:
    [...]
    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.
    [...]

    Aren't Tiny C and TCC the same thing? Did you mean "at least a
    magnitude faster than gcc"?


    Yes.

    --- 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 15:43:03 2026
    Richard Harnden <richard.nospam@gmail.invalid> writes:
    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.

    Sorry if I was unclear.

    I was referring to a hypothetical header whose name starts with 'e',
    and using a consistent convention for creating macro names from header
    names that avoids reserved identifiers.

    NUMBER_GENERATOR_H is not reserved. EVENT_H (for "event.h",
    a header file in my /usr/include directory) is.

    (That actual header file uses "EVENT1_EVENT_H_INCLUDED_" -- not
    what I'd use, but vanishingly unlikely to be a problem in practice.
    It could also be argued that it's part of the implementation.)

    --
    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 Keith Thompson@3:633/10 to All on Wed Sep 9 15:52:37 2026
    Janis Papanagnou <janis_papanagnou+ng@hotmail.com> writes:
    [...]
    (Please, for the sake of the people that haven't killfiled you, use an online-translator to create comprehensible texts! - In case that your
    native language *is* English I suggest to translate your text to some
    other language and then back to English; the translators are obviously
    good enough to fix your language or writing problems in that process.)

    The above was addressed to "fir". As I recall, his native language
    is Polish.

    "fir" has been posting here for a long time. Here's something our own
    David Brown wrote about him in 2015. I can't directly vouch for its
    accuracy, but it seems plausible.

    He does not have dyslexia. English is a second language for him,
    but he is capable of writing much better than he does (I have seen
    him do so) - he /intentionally/ writes in this manner because he
    considers himself too much of a grand thinker and philosopher to
    lower himself to our mere "commoner" language. As far as I
    understand it, he writes in a similar manner in his own language.
    Many of us have tried to suggest he changes his manner for his own
    good as well as ours - but to no avail.

    Reference:

    Subject: Re: Recursion or loop, design questions
    Date: Wed, 05 Aug 2015 08:45:25 +0200
    Message-ID: <mpsbb5$3s9$1@dont-email.me>

    I suggest that one more attempt to get fir to write clearly is
    unlikely to be effective. I've solved the problem for myself by
    adding him to my killfile.

    --
    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 Thu Sep 10 01:00:31 2026
    Keith Thompson pisze:
    Janis Papanagnou <janis_papanagnou+ng@hotmail.com> writes:
    [...]
    (Please, for the sake of the people that haven't killfiled you, use an
    online-translator to create comprehensible texts! - In case that your
    native language *is* English I suggest to translate your text to some
    other language and then back to English; the translators are obviously
    good enough to fix your language or writing problems in that process.)

    The above was addressed to "fir". As I recall, his native language
    is Polish.

    "fir" has been posting here for a long time. Here's something our own
    David Brown wrote about him in 2015. I can't directly vouch for its accuracy, but it seems plausible.

    He does not have dyslexia. English is a second language for him,
    but he is capable of writing much better than he does (I have seen
    him do so) - he /intentionally/ writes in this manner because he
    considers himself too much of a grand thinker and philosopher to
    lower himself to our mere "commoner" language. As far as I
    understand it, he writes in a similar manner in his own language.
    Many of us have tried to suggest he changes his manner for his own
    good as well as ours - but to no avail.

    Reference:

    Subject: Re: Recursion or loop, design questions
    Date: Wed, 05 Aug 2015 08:45:25 +0200
    Message-ID: <mpsbb5$3s9$1@dont-email.me>

    I suggest that one more attempt to get fir to write clearly is
    unlikely to be effective. I've solved the problem for myself by
    adding him to my killfile.


    funny, honestly i dont know why i write such way as i write

    i suspect its in big extent becouse if i think on c language ideas im
    kina highly focused and 'turning' to think on all this letters is on
    kinda different plane so it annoys me, its hard to be focused on
    thinking on higher c topics and on editing sentences, translating text
    in google or chat gpt..its robably possible but so wearing that the
    oryginal thoughts would sufer too much

    i may say hovver i got some friends on some irc i used for years and
    they never complained for some reason..though i wrote in polish there
    and on chat you look on text much more than when you write messages on
    usenet

    --- 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 16:29:58 2026
    Lane W <cactus_DAC@yahoo.com> writes:
    fir wrote:
    [...]
    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?

    Please refrain from mentioning my name in any future posts. I have
    no interest in watching you embarrass yourself.

    I intend to add you to my killfile (technically, my Gnus scorefile),
    with the result that I will never see any of your posts here.
    If your embarrassing behavior improves in the next few days,
    I'll consider not doing so. To be clear, this is not a threat.
    It's simply something I intend to do to make my own experience here
    a little better, by giving me a view of comp.lang.c that does not
    include you. Others will do as they wish.

    --
    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 Thu Sep 10 06:16:21 2026
    On 2026-09-10 00:52, Keith Thompson wrote:
    Janis Papanagnou <janis_papanagnou+ng@hotmail.com> writes:
    [...]
    (Please, for the sake of the people that haven't killfiled you, use an
    online-translator to create comprehensible texts! - In case that your
    native language *is* English I suggest to translate your text to some
    other language and then back to English; the translators are obviously
    good enough to fix your language or writing problems in that process.)

    The above was addressed to "fir". [...]

    Yes.

    [ background info snipped ]

    I suggest that one more attempt to get fir to write clearly is
    unlikely to be effective. I've solved the problem for myself by
    adding him to my killfile.

    Thanks for the the info and warning. - Actually he is already in my
    killfile, so I see his writings only when he gets quoted my someone.

    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 Thu Sep 10 06:50:10 2026
    On 2026-09-09 15: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?

    What makes you think so? - That is not only wrong, it's completely
    absurd! (I also wonder about that personal obsession.)

    [...]

    [ snip ]

    (Yes to all you wrote and that I snipped just for brevity.)


    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.

    Let me add that in case there's some deeper idea behind any criticized
    code it could have been explained by the poster. (Not that it is likely
    that the regulars with decades years of experience would not be able to
    tell apart good and bad code. - But that would at least be a sign that
    the poster is interested in discussions about any pros and the cons of
    some particular code.)

    (My post here is intended
    as constructive criticism - it is not a personal attack.)

    (I think no sane person would have suspected bad intent of your post.)

    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 Thu Sep 10 07:16:49 2026
    On 2026-09-09 16:16, Richard Harnden wrote:
    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.

    This was also my first thought when I read Keith's formulation.
    On a second thought I presumed he meant that with such a method
    some other header names (those starting with 'e') might lead to
    problems; I suppose only if there's clashes with existing ones
    in the actual environment (or as part of the standard).

    Personally I think that it's not good to twist ones own coherent
    naming conventions only due to the fact that there's these (IMO)
    very unfortunate exceptions for sub-ranges of these identifiers,
    and some (very low?) probability that there may be clashes.

    I don't known when the E-words found their way into the standard.
    Back in the days we had used names primarily resembling the file
    names. (We never encountered a problem. And, in case there would
    have been one, it were certainly not a situation that couldn't
    then be specifically handled and resolved, I'd think.)

    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 Thu Sep 10 08:45:53 2026
    On 2026-09-10 00:30, bart wrote:
    On 09/09/2026 22:26, Janis Papanagnou wrote:
    [...]

    Myself I'm favoring _to be able_ to import only what I need and not the
    whole bunch of existing things of a module (with all potential implicit
    and explicit consequences).

    Why? What is the advantage of so much micromanagement?

    The advantages of _modularity_ are for example to structure entities
    that may be typically used together or to restrict yourself to the
    subset of what you actually need. (Neither an "include all" nor an
    "include value_x_of_y" are usually sensible choices!) - You may want
    to inspect the various options you have in other languages (inspect,
    just for example, Java - beyond any personal liking of that language).


    Is even the pain of having to do '#include <string.h>' not enough when
    your code uses string functions, you would prefer to list them
    individually too?!

    No. What makes you think so? (And it is also no "pain" for me, BTW.)

    But if all I need from the string class is, say, strcmp() then it is
    completely sensible to be able to include just that. (This is not "C"
    but explaining just the principle of import or export control here.)

    If it turns out that I need more I can include the whole "tool-chest"
    (unless I get name clashes that a specific import would prevent).


    With other languages, do you also need to specify importing individual variables, enumerations, types, structs and macros?

    That depends on the specific language. - Note that I'm not competent
    to know all the module concepts of the many languages; I know just a
    few. And we're anyway speaking about the principles of modularity and
    its control.

    Ideally you may control the import level (all, or selected items) to
    your needs. Typically the modules are (or should be) structured in a
    way that elements that "belong together" are collected in a module,
    so that with a single import you have all you need for using it; as
    you write in your question this may be types, functions, singleton
    objects, or whatever the respective language supports.

    For example; my recent Algol 68 option parser defines the necessary
    types and the (exported) function to handle the options. (All other
    internally used functions are hidden.) Or my array shuffler function
    uses a swap operator, but since that is useful also generally I have
    it visible in the module for use. In an encryption module I have the
    functions to create the subkey-sequence, the encryption/decryption
    functions, data types resembling the entities you use with these
    functions (e.g. 64-bit and 56-bit integrals). - So these facilities
    provide all the _necessary_ in one module each. But there may also
    be tool-chests-like modules; and in this case you may prefer to just
    pick the requested entities if the subset is small. - For example my ansi-controls module is a huge collection of functions; I'd like to
    just pick the 5 or 6 functions I'm needing (but with the language I'm
    using I can only pick an include file as a whole; unless I split the
    functions myself in sub-groups - good that we spoke about that; I'll
    probably do that to separate the colors at least - anyway there's a
    lot of entries that I'd prefer not to pollute my name space).

    Note also that languages may provide structuring means that allow an
    own level of modularization. Consider for example the object oriented
    languages where you collect things that belong together in classes.

    BTW, you may want to consider reading more about modularity; B. Meyer
    has an introductory small chapter about aspects in his "OO Software Development" book. (I'm sure there's plenty other resources.) You can
    also search the Web on principles and advantages including control of modularization.


    An enumeration set may have hundreds of names; do you have to list all
    of them? That would be insane.

    Yes, that would be insane. - How do you manage it to breed such absurd
    ideas?!

    Didn't there for a moment appear the option in your mind that it's not
    about having to do that in one extreme or in another!?


    I'd originally complained about having to list modules individually in
    in each file; this would be literally magnitudes worse.

    It's not about "having to"; it's about _having the option_ to do,
    depending on the actual case (and of course primarily depending on
    the methods that any specific language provides).


    You might as well put each entity into its own module, and have a subset
    of 1000 modules to manage instead - in each of the 1000 functions.

    Why would you do that? I wouldn't. - You completely missed the point.


    You people seem to like making life difficult. Well, go ahead!

    Nonsense. - You seem to be stubbornly focused on some "idee fixe" you
    have, incapable of evading your own mental cage.


    Myself I'm favoring _to be able_ to import only what I need and not the whole bunch of existing things of a module (with all potential implicit and explicit consequences).

    Which consequences are these? If there's too much unrelated stuff in a module, that suggests it is poorly structured.

    Yes. (As I've expanded on.)


    If you import modules A and B, and use functions from each, but some may clash (say you want F from A but not F from B), then that's not a
    problem because you will say A.F or B.F.

    Yes, if namespaces are supported.

    But that's also not that "simple" or clear as you pretend. - Consider
    for example C++ with its stream output; would you really write as in
    this _simple_ example - there's yet more common things with streams,
    like standard-modifiers (e.g. std::oct, std:: setw()) that may often
    complicate the expression WRT legibility! - always 'std::' like

    std::cout << "hello world" << std::endl;

    or prefer an extensive all-is-the-least-"burden" directive

    using std;

    and for all the many output commands just the better legible

    cout << "hello world" << endl;

    Or would you take the "burden" to restrict your imports for this common
    case once with the _specific_ references like

    using std::cout;
    using std::endl;

    I'd say, it depends. - And I think it's good to have full control over
    all the sensible options.


    If you want to use 'using' because you don't want to type 'A.' or 'B.',
    just F and it will be from a specific import, that /that/ would be bad
    form. In any case, there are better ways.

    I suppose you are referring to the C++ model here. - Yes, in C++ you
    have the option from explicitly qualifying the entity to "get all"
    into the namespace.

    The point is that you should have the possibility to modularize, and
    to control it.

    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 Thu Sep 10 09:07:24 2026
    On 09/09/2026 22:39, bart wrote:
    On 09/09/2026 20:39, David Brown wrote:
    On 09/09/2026 19:34, bart wrote:

    You see the same thing [with] 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?


    It's not hard to make programs that are slow for a particular task.
    Once you have reached a certain point, however, it's far harder to
    make them much faster.˙ I believe there was a mainstream assembler
    that had a particularly poor algorithm somewhere, resulting in
    surprisingly long run times once input was over a certain size.˙ I
    don't imagine it is a general problem, however.

    NASM, MASM, or both?


    Having never had use for any assembler on x86, I don't know - it's just something I remember hearing about. From your numbers, it's probably
    the nasm bug.

    I know there is a long standing bug in NASM which leads to result like these, for this 270Kloc input (actually, an SQL test compiled into three different x64 ASM formats):

    ˙˙ nasm -O0 -fwin64˙˙˙˙ 250˙˙˙ seconds (to .obj)
    ˙˙ yasm -fwin64˙˙˙˙˙˙˙˙˙˙ 1.06 seconds (to .obj)
    ˙˙ as˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙ 0.65 seconds (to .o)
    ˙˙ aa˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙ 0.10 seconds (to .exe)

    Obviously, 'aa' is my product. And clearly, NASM has something wrong. (Without -O0, it would be 60% slower!)

    MASM (as 'ml64.exe') had its own bug to do with using RESB in a .DATA segment; it got exponentially slower with the size of the block. (I no longer have it to test.)

    For whole-program compilers that generate a single ASM file, assembly
    speed is critical.



    --- 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 Thu Sep 10 09:11:56 2026
    On 09/09/2026 17: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.

    Ugly code.

    Difficult to maintain.



    To me, the problem with code written like this is that it is easily misinterpreted by the reader. Reversing the order would help
    enormously, as would adding "else" clauses.

    (Bart did not pick that ordering, merely copied it from Lane's 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 Thu Sep 10 09:32:26 2026
    On 09/09/2026 22:18, bart wrote:
    On 09/09/2026 20:45, David Brown wrote:
    On 09/09/2026 20:12, bart wrote:

    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.
    Please stop paraphrasing me (and other people) incorrectly.˙ Instead,
    just assume that you have misunderstood what people have said, and
    continue discussing them in the relevant thread in the hope that you
    eventually understand it.˙ I am happy to discuss many things with you,
    but I find your repeated misquoting extremely frustrating.
    You said this:

    As I showed in my timings, in real use, that [reducing headers by 95%] 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.

    In an earlier post (09:18 BST today) you said:

    ˙ Trying to optimise or flatten header sets for some library would be
    a waste of effort - the effect is too minor.

    Both sound very much as though consider it a waste of time.

    You have managed to read, then quote, what I wrote - and you still do
    not see how it differs substantially from what you /claim/ I said?

    I gave numbers demonstrating that, for /me/, with /my/ code, no
    reduction or simplification of headers could have an effect on /my/
    build times that was big enough to be worth /my/ time.

    I also, several times, said that it is possible that it would be helpful
    for widely used libraries to provide more efficient headers. I don't
    think it is often the case, but I am open to the possibility.

    I have said nothing about "reducing a large, complex mass of headers
    into one compact file 95% smaller" - how could I have commented on a circumstance that you did not mention until later?

    If a library has a collection of headers that can be reduced by a factor
    of 20 without affecting functionality (including any helpful comments),
    then it seems likely that the project could be improved by a
    re-factorisation and cleanup. The prime motivation would be improving maintainability, making the headers easier to navigate and understand,
    and reducing the risk of errors from out-of-sync duplications. It may
    also marginally reduce build times for library users, but that would be
    a bonus side-effect, not the reason for such a cleanup.



    You are also ignoring a simple fact: how large is a typical source file
    size in C; 1000 lines maybe?

    Well each .c file that includes SDK.h needs to first process 82,000 / unique/ lines of source, before getting around to those 1000 lines.

    But that's also ignoring that a lot more than 82Kloc needs to be either processed or skipped since many are re-included: there are 466
    #includes! In fact here are the figures from my compiler:

    ˙ Total lines processed:˙ 551,674

    Of those, 150,000 are conditional false blocks that skipped over, but it still leaves 400,000 lines.

    This is 400Kloc for a ONE module of 1Kloc, and there could be other
    modules pulling in the same header. So, I would say that is quite
    dominant, for a non-optimising build.


    Compilers chew through typical C header stuff at high speed. They are
    usually nothing more than macros and simple declarations. With the
    exception of occasional inline function definitions, it's all quickly digested. The time and effort of compiling - at least for grown-up
    compilers - is in code analysis, inter-procedural optimisations, error analysis, register allocation algorithms, variable lifetime analysis,
    code generation, and countless optimisation passes. The average "lines
    of code handled per second" speed is probably a thousand times faster
    while reading the SDL.h headers than while handling the user 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 Thu Sep 10 09:48:59 2026
    On 10/09/2026 00:30, bart wrote:
    On 09/09/2026 22:26, Janis Papanagnou wrote:
    On 2026-09-09 20:12, bart wrote:
    On 09/09/2026 02:59, Waldek Hebisch wrote:
    [...]

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

    I fear you're just exposing your very limited perception and experience
    here. (And en passant probably also the mindset of a technocratic paper
    pusher than a software designer.)

    Myself I'm favoring _to be able_ to import only what I need and not the
    whole bunch of existing things of a module (with all potential implicit
    and explicit consequences).
    Why? What is the advantage of so much micromanagement?

    Consider modules in Python, since that is a language with "real" modules
    and with which many people are familiar.

    # foobar.py
    def foo() : return "foo"
    def bar() : return "bar"


    Another file user.py wants to use "foo" from "foobar.py". They can do
    so in three main ways :

    1. Specific inclusion

    from foobar import foo
    x = foo()


    2. Global namespace inclusion

    from foobar import *
    x = foo()


    3. Module namespace inclusion

    import foobar
    x = foobar.foo()


    Each type of import has its own advantages and disadvantages.

    Type 1 would need micro-management if you want a lot of symbols from a
    module. But if you only need a small number, it can keep things neat -
    you only see what you actually want to use. And if the imported module
    only really exports a single name (like "my_class.py" exporting
    "My_Class"), it's a neat solution that avoids later code clutter from
    having to specify the module name.

    Type 2 lets you immediately use all the identifiers from the module, but causes a lot of problems if things change in the future. Maybe your own
    code has a function "fluff", and a later version of "foobar.py" also
    adds a function "fluff". That is not going to be good.

    Type 3 lets you conveniently import all the exported symbols from the
    module, but you need to specify the namespace when using them.


    As I see it, Janis favours that kind of flexibility for modules (though
    of course the details may differ for different languages).


    You seem to be favouring just type 2 - or even a "from * import *"
    solution. That might be convenient for a personal language where you
    are the only one ever writing the code - you know there are no
    collisions, because you wrote everything. For anyone else, working
    outside a bubble, it is unscalable.


    --- 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 Thu Sep 10 10:11:52 2026
    On 09/09/2026 23:07, Janis Papanagnou wrote:
    On 2026-09-09 16:23, Richard Harnden wrote:
    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:



    = 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

    Yes, that's a long and well-known disadvantage of '=' for assignments.

    Sometimes "=" is used for "assignment" or "definition" in mathematics,
    as well as for equality comparison. But mathematics has the advantage
    that the meaning is generally clear from the context.

    Fun fact - in Metafont and MetaPost, "=" is used in a symmetrical
    fashion. You can write "x = 10" or "10 = x". You can also write "x +
    2*y = 40, 45 - y = 3 * x". These are not exactly assignment statements
    - they are declarations that the language can use to figure out the
    correct values for the variables.


    But there need not be a problem using '=' for assignments and also
    for comparisons if the respective languages could tell them apart by
    context and with appropriate semantic rules.

    Agreed. In my "dream language", assignment would be a statement, not an expression, which lets you use the same symbol. Indeed, assignment
    would be very rare - normally variables would be initialised once, and
    never changed.



    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

    (Please, for the sake of the people that haven't killfiled you, use an online-translator to create comprehensible texts! - In case that your
    native language *is* English I suggest to translate your text to some
    other language and then back to English; the translators are obviously
    good enough to fix your language or writing problems in that process.)


    As I understand it from previous discussions, fir writes equally badly
    in his native tongue - so online translators would have as much trouble
    as we do. He considers standardised spelling and grammar as a
    limitation on his genius creativity, I think. But sometimes his posts
    can lead to interesting and topical discussions, which is always nice.




    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From bart@3:633/10 to All on Thu Sep 10 13:09:42 2026
    On 10/09/2026 07:45, Janis Papanagnou wrote:
    On 2026-09-10 00:30, bart wrote:
    On 09/09/2026 22:26, Janis Papanagnou wrote:
    [...]

    Myself I'm favoring _to be able_ to import only what I need and not the
    whole bunch of existing things of a module (with all potential implicit
    and explicit consequences).

    Why? What is the advantage of so much micromanagement?

    The advantages of _modularity_ are for example to structure entities
    that may be typically used together or to restrict yourself to the
    subset of what you actually need.

    OK, that's modules. A module should already define the subset of its
    entities that are exported.

    (Neither an "include all" nor an
    "include value_x_of_y" are usually sensible choices!) - You may want
    to inspect the various options you have in other languages (inspect,
    just for example, Java - beyond any personal liking of that language).

    This is the language that looks like this:

    public class HelloWorld {
    public static void main(String[] args) {
    System.out.println("Hello, World");
    }
    }

    Whereas mine looks like so:

    proc main =
    println "Hello, World"
    end

    26 tokens versus 6 tokens. My comments are to do with minimising clutter
    - and also maintenance - when using a modules scheme, so this is not a
    good model!



    Is even the pain of having to do '#include <string.h>' not enough when
    your code uses string functions, you would prefer to list them
    individually too?!

    No. What makes you think so? (And it is also no "pain" for me, BTW.)

    So you enjoy the dance of writing 'printf', 'strcmp' etc and having to interrupt your train of thought, go to the top of the module to write
    the necessary include, then get back to where you where?

    But if all I need from the string class is, say, strcmp() then it is completely sensible to be able to include just that.

    And here you want to make it even worse, by needing to do that dance for
    the dozens of individual functions you might need instead of just that
    handful of headers.

    With C, you do #include <GTK.h>, and you instantly have the names of
    10,000 functions, types, variables, macros, and enums invading your
    module scope, but that is apparently fine.

    If it turns out that I need more I can include the whole "tool-chest"
    (unless I get name clashes that a specific import would prevent).

    I can understand this in Python, where there is no export control: every top-level name in a module would be visible to the importer.

    But usually module schemes include such control.

    Ideally you may control the import level (all, or selected items) to
    your needs.

    This is the key thing. I've already seen that when using only modules to control what is or isn't imported, it was an imposition to have to
    specify the same thing in every module. So module A may import B, C, F,
    while B imports A, C, F, H, while C includes ....

    That resulted in what to me was an anti-pattern.

    But, you want to make it even worse, but having possible a hundred
    things you need to specify in EVERY MODULE.

    And then one day, you decide to refactor a module into two modules, and
    now each will need a different subset of that 100.

    BTW what happens if you import a function which is not used; will the
    language complain? If not, then what was the point of specifying imports
    to that level of granularity?


    For example; my recent Algol 68 option parser defines the necessary
    types and the (exported) function to handle the options. (All other internally used functions are hidden.) Or my array shuffler function
    uses a swap operator, but since that is useful also generally I have
    it visible in the module for use. In an encryption module I have the functions to create the subkey-sequence, the encryption/decryption
    functions, data types resembling the entities you use with these
    functions (e.g. 64-bit and 56-bit integrals). - So these facilities
    provide all the _necessary_ in one module each. But there may also
    be tool-chests-like modules;
    Does Algol68 have such a feature? Does it even have modules?!

    and in this case you may prefer to just
    pick the requested entities if the subset is small.

    The tool-chest module will usually still be loaded or statically
    compiled as a whole even if you only want part.

    In that case, if you want to use a specific export from it, what is the
    point, or benefit, of needing to explicitly name that export?

    And why can't the 'picking' be inferred from the act of calling or using
    that export?

    (In the AS assembler, if you want to import function 'puts', say, then
    you just use that name. If not defined in the file, it assumes it is
    imported.

    In my AA assembler, the name is written as 'puts*' to mark it as
    imported. Assemblers like NASM or MASM however require all imported
    symbols to be declared first. But, this is assembly, not a HLL!)


    - For example my
    ansi-controls module is a huge collection of functions; I'd like to
    just pick the 5 or 6 functions I'm needing (but with the language I'm
    using I can only pick an include file as a whole; unless I split the functions myself in sub-groups - good that we spoke about that; I'll
    probably do that to separate the colors at least - anyway there's a
    lot of entries that I'd prefer not to pollute my name space).

    Are there not namespaces that will contain those imported names?

    Note also that languages may provide structuring means that allow an
    own level of modularization. Consider for example the object oriented languages where you collect things that belong together in classes.

    BTW, you may want to consider reading more about modularity; B. Meyer
    has an introductory small chapter about aspects in his "OO Software Development" book. (I'm sure there's plenty other resources.) You can
    also search the Web on principles and advantages including control of modularization.

    I've worked with quite a few module schemes of my own so have a lot of experience or what works and what doesn't. My current one is so far the
    best for my purposes. If I want to add a simple library function, then I
    might write it like this:

    global func factorial(int n)int =
    ....
    end

    I write that in a source file called mylib.m say. To use it in my
    application, I add this line to its lead module:

    module mylib

    And, that's it! All modules of my app can now call factorial(). They
    don't even need to write mylib.factorial() unless there's a clash. And I
    don't need to separately compile mylib.m - this is whole program
    compilation, it's done automatically.

    (There's bit more to it because I have a 2-level structure, but that's
    pretty much it for the body of the app.)

    I really doubt whether those links can improve matters. I want
    modularisation without any of the headaches.


    An enumeration set may have hundreds of names; do you have to list all
    of them? That would be insane.

    Yes, that would be insane. - How do you manage it to breed such absurd ideas?!

    An enumeration name is an identifier like any other, that could
    conceivably 'pollute' your name space. So, if selective imports are
    allowed, why wouldn't they apply here too?

    You might as well put each entity into its own module, and have a
    subset of 1000 modules to manage instead - in each of the 1000 functions.

    Why would you do that? I wouldn't. - You completely missed the point.

    It would be just as stupid. (But I've seen projects like this, with
    hundreds of source files, then you discover that the whole project is
    only about 2Kloc!)



    You people seem to like making life difficult. Well, go ahead!

    Nonsense. - You seem to be stubbornly focused on some "idee fixe" you
    have, incapable of evading your own mental cage.

    I don't like the idea of micromanaging imports an identifier at a time.

    You've spent your whole post defending that, while also stressing it is optional.

    Well, I don't even want it as an option!

    I'm against needing declarations at all, except the absolute minimum.
    And selecting imports are declarations.


    But that's also not that "simple" or clear as you pretend. - Consider
    for example C++ with its stream output; would you really write as in
    this _simple_ example - there's yet more common things with streams,
    like standard-modifiers (e.g. std::oct, std:: setw()) that may often complicate the expression WRT legibility! - always 'std::' like

    ˙ std::cout << "hello world" << std::endl;

    or prefer an extensive all-is-the-least-"burden" directive

    ˙ using std;

    and for all the many output commands just the better legible

    ˙ cout << "hello world" << endl;

    C++ is an even worse role model than Java. That cout example is only marginally better than the version with std::. I like no-nonsense code
    that looks like this:

    println "hello world"


    The point is that you should have the possibility to modularize, and
    to control it.
    The modularisation is there, but this isn't really controlling it. It's
    not the like the name you are importing is Private; it will be Public or Global.

    You're just adding a pointless barrier to it in the importing module.



    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From fir@3:633/10 to All on Thu Sep 10 14:37:04 2026
    bart pisze:

    ˙public class HelloWorld {
    ˙˙˙ public static void main(String[] args) {
    ˙˙˙˙˙˙˙ System.out.println("Hello, World");
    ˙˙˙ }
    ˙}

    Whereas mine looks like so:

    ˙ proc main =
    ˙˙˙˙˙ println "Hello, World"
    ˙ end


    in c it would be

    main() printf("Hello, World");

    if they would allow skkip {}

    main() { printf("Hello, World"); }

    in this short cases like it is in ifs

    in my proto-extended-c i compile it is

    main { printf "Hello, World" }

    it is from this compiled example (this void i should remove some way
    but it was under work and im not touching it recently)

    void ProcessMouseMove mouse_x mouse_y { }


    void OnResize { RunFrame }
    void main
    {
    RegisterMouseMove &ProcessMouseMove
    RegisterKeyDown &ProcessKeyDown
    RegisterOnResize &OnResize
    RegisterRunFrame &RunFrame
    SetSleepValue 5, SetScaleOnResize 0, Set3dDrawingMode 1
    SetupWindow4 " Example Green Fire App compiled by Furia \x00"
    20 20 0.9 0.9 600

    }




    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From fir@3:633/10 to All on Thu Sep 10 14:38:18 2026
    Janis Papanagnou pisze:
    On 2026-09-10 00:52, Keith Thompson wrote:
    Janis Papanagnou <janis_papanagnou+ng@hotmail.com> writes:
    [...]
    (Please, for the sake of the people that haven't killfiled you, use an
    online-translator to create comprehensible texts! - In case that your
    native language *is* English I suggest to translate your text to some
    other language and then back to English; the translators are obviously
    good enough to fix your language or writing problems in that process.)

    The above was addressed to "fir". [...]

    Yes.

    [ background info snipped ]

    I suggest that one more attempt to get fir to write clearly is
    unlikely to be effective.˙ I've solved the problem for myself by
    adding him to my killfile.

    Thanks for the the info and warning. - Actually he is already in my
    killfile, so I see his writings only when he gets quoted my someone.

    Janis


    welcome in keith team ;c


    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From fir@3:633/10 to All on Thu Sep 10 15:11:14 2026
    fir pisze:
    bart pisze:

    ˙˙public class HelloWorld {
    ˙˙˙˙ public static void main(String[] args) {
    ˙˙˙˙˙˙˙˙ System.out.println("Hello, World");
    ˙˙˙˙ }
    ˙˙}

    Whereas mine looks like so:

    ˙˙ proc main =
    ˙˙˙˙˙˙ println "Hello, World"
    ˙˙ end


    in c it would be

    main() printf("Hello, World");

    if they would allow skkip {}

    main() { printf("Hello, World"); }

    ˙in this short cases like it is in ifs

    in my proto-extended-c i compile˙ it is

    main { printf "Hello, World" }

    it is from this compiled example (this void i should remove some way
    but it was under work and im not touching it recently)

    ˙void ProcessMouseMove mouse_x mouse_y { }


    ˙void OnResize { RunFrame }
    ˙void main
    ˙{
    ˙˙˙˙˙˙˙˙ RegisterMouseMove &ProcessMouseMove
    ˙˙˙˙˙˙˙˙ RegisterKeyDown &ProcessKeyDown
    ˙˙˙˙˙˙˙˙ RegisterOnResize &OnResize
    ˙˙˙˙˙˙˙˙ RegisterRunFrame &RunFrame
    ˙˙˙˙˙˙˙˙ SetSleepValue 5, SetScaleOnResize 0, Set3dDrawingMode 1
    ˙˙˙˙˙˙˙˙ SetupWindow4 " Example Green Fire App compiled by Furia \x00"
    20 20˙ 0.9 0.9 600

    ˙}



    this void is beoouse i must denote definition and yet has no idea


    from this gemeral bara naked function all conventios im quite happy

    gere function calls i name "logical lines" as compiler just breaks
    lines on logical lines on newline or ","

    so

    void main
    {
    SetSleepValue 5
    SetScaleOnResize 0
    Set3dDrawingMode 1
    SetupWindow4 " Example Green Fire App compiled by Furia \x00"
    20 20 0.9 0.9 600

    }

    ise the same as

    void main
    {
    SetSleepValue 5, SetScaleOnResize 0, Set3dDrawingMode 1,
    SetupWindow4 " Example Green Fire App compiled by Furia \x00"
    20 20 0.9 0.9 600

    }
    also blocks may be instead of form {a,b,c,d,e} be a,b,c,d,e;

    so above may be

    void main
    SetSleepValue 5, SetScaleOnResize 0, Set3dDrawingMode 1,
    SetupWindow4 " Example Green Fire App compiled by Furia \x00"
    20 20 0.9 0.9 600 ;


    as fay as i remember (im not sure right now if function ending sign i
    chose as ";" "." ";." or smthe (possibly it need to be something like ;.
    but it yet is not decided

    there also may be optional :

    void main: SetSleepValue 5, SetScaleOnResize 0, Set3dDrawingMode 1, SetupWindow4 " Example Green Fire App compiled by Furia \x00"
    20 20 0.9 0.9 600;

    i emen is optional if after definition header there is newline

    those things are somewhat clear (maybe this ending function if there is
    no {} is not cleer but other seem clear

    but many things are yet not resolved (like if statements or even im not
    sure as to assigments, for loops -s till not chosen


    but the bare naked form of function calls is imo impressive









    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From fir@3:633/10 to All on Thu Sep 10 15:16:02 2026
    fir pisze:
    fir pisze:
    bart pisze:

    ˙˙public class HelloWorld {
    ˙˙˙˙ public static void main(String[] args) {
    ˙˙˙˙˙˙˙˙ System.out.println("Hello, World");
    ˙˙˙˙ }
    ˙˙}

    Whereas mine looks like so:

    ˙˙ proc main =
    ˙˙˙˙˙˙ println "Hello, World"
    ˙˙ end


    in c it would be

    main() printf("Hello, World");

    if they would allow skkip {}

    main() { printf("Hello, World"); }

    ˙˙in this short cases like it is in ifs

    in my proto-extended-c i compile˙ it is

    main { printf "Hello, World" }

    it is from this compiled example (this void i should remove some way
    but it was under work and im not touching it recently)

    ˙˙void ProcessMouseMove mouse_x mouse_y { }


    ˙˙void OnResize { RunFrame }
    ˙˙void main
    ˙˙{
    ˙˙˙˙˙˙˙˙˙ RegisterMouseMove &ProcessMouseMove
    ˙˙˙˙˙˙˙˙˙ RegisterKeyDown &ProcessKeyDown
    ˙˙˙˙˙˙˙˙˙ RegisterOnResize &OnResize
    ˙˙˙˙˙˙˙˙˙ RegisterRunFrame &RunFrame
    ˙˙˙˙˙˙˙˙˙ SetSleepValue 5, SetScaleOnResize 0, Set3dDrawingMode 1
    ˙˙˙˙˙˙˙˙˙ SetupWindow4 " Example Green Fire App compiled by Furia
    \x00" 20 20˙ 0.9 0.9 600

    ˙˙}



    this void is beoouse i must denote definition and yet has no idea


    from this gemeral bara naked function all conventios im quite happy

    gere function calls˙ i name "logical lines" as compiler just breaks
    lines on logical lines on newline or ","

    so

    ˙void main
    ˙˙ {
    ˙˙˙˙˙˙˙˙˙˙ SetSleepValue 5
    ˙˙˙˙˙˙˙˙˙ SetScaleOnResize 0
    ˙˙˙˙˙˙˙˙˙˙ Set3dDrawingMode 1
    ˙˙˙˙˙˙˙˙˙˙ SetupWindow4 " Example Green Fire App compiled by Furia \x00"
    ˙20 20˙ 0.9 0.9 600

    ˙˙ }

    ise the same as

    void main
    ˙˙ {
    ˙˙˙ SetSleepValue 5, SetScaleOnResize 0, Set3dDrawingMode 1,
    SetupWindow4 " Example Green Fire App compiled by Furia \x00"
    ˙20 20˙ 0.9 0.9 600

    ˙˙ }
    also blocks may be instead of form {a,b,c,d,e} be a,b,c,d,e;

    so above may be

    void main
    ˙˙˙ SetSleepValue 5, SetScaleOnResize 0, Set3dDrawingMode 1,
    SetupWindow4 " Example Green Fire App compiled by Furia \x00"
    ˙20 20˙ 0.9 0.9 600 ;


    as fay as i remember (im not sure right now if function ending sign i
    chose as ";" "." ";." or smthe (possibly it need to be something like ;.
    but it yet is not decided


    or maybe it was ";;" as an end - probably this should be just some
    unicode sign as ending function definition denoter (even something like small/medium rectangle ) but im trying to go as far in this syntax
    thining and cleaning as far as i can go



    there also may be optional :

    void main: SetSleepValue 5, SetScaleOnResize 0, Set3dDrawingMode 1, SetupWindow4 " Example Green Fire App compiled by Furia \x00"
    ˙20 20˙ 0.9 0.9 600;

    i emen is optional if after definition header there is newline

    those things are somewhat clear (maybe this ending function if there is
    no {} is not cleer but other seem clear

    but many things are yet not resolved (like if statements or even im not
    sure as to assigments, for loops -s till not chosen


    but the bare naked form of function calls is imo impressive










    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From fir@3:633/10 to All on Thu Sep 10 15:28:39 2026
    fir pisze:
    fir pisze:
    fir pisze:
    bart pisze:

    ˙˙public class HelloWorld {
    ˙˙˙˙ public static void main(String[] args) {
    ˙˙˙˙˙˙˙˙ System.out.println("Hello, World");
    ˙˙˙˙ }
    ˙˙}

    Whereas mine looks like so:

    ˙˙ proc main =
    ˙˙˙˙˙˙ println "Hello, World"
    ˙˙ end


    in c it would be

    main() printf("Hello, World");

    if they would allow skkip {}

    main() { printf("Hello, World"); }

    ˙˙in this short cases like it is in ifs

    in my proto-extended-c i compile˙ it is

    main { printf "Hello, World" }

    it is from this compiled example (this void i should remove some way
    but it was under work and im not touching it recently)

    ˙˙void ProcessMouseMove mouse_x mouse_y { }


    ˙˙void OnResize { RunFrame }
    ˙˙void main
    ˙˙{
    ˙˙˙˙˙˙˙˙˙ RegisterMouseMove &ProcessMouseMove
    ˙˙˙˙˙˙˙˙˙ RegisterKeyDown &ProcessKeyDown
    ˙˙˙˙˙˙˙˙˙ RegisterOnResize &OnResize
    ˙˙˙˙˙˙˙˙˙ RegisterRunFrame &RunFrame
    ˙˙˙˙˙˙˙˙˙ SetSleepValue 5, SetScaleOnResize 0, Set3dDrawingMode 1
    ˙˙˙˙˙˙˙˙˙ SetupWindow4 " Example Green Fire App compiled by Furia
    \x00" 20 20˙ 0.9 0.9 600

    ˙˙}



    this void is beoouse i must denote definition and yet has no idea


    from this gemeral bara naked function all conventios im quite happy

    gere function calls˙ i name "logical lines" as compiler just breaks
    lines on logical lines on newline or ","

    so

    ˙˙void main
    ˙˙˙ {
    ˙˙˙˙˙˙˙˙˙˙˙ SetSleepValue 5
    ˙˙˙˙˙˙˙˙˙˙ SetScaleOnResize 0
    ˙˙˙˙˙˙˙˙˙˙˙ Set3dDrawingMode 1
    ˙˙˙˙˙˙˙˙˙˙˙ SetupWindow4 " Example Green Fire App compiled by Furia \x00"
    ˙˙20 20˙ 0.9 0.9 600

    ˙˙˙ }

    ise the same as

    void main
    ˙˙˙ {
    ˙˙˙˙ SetSleepValue 5, SetScaleOnResize 0, Set3dDrawingMode 1,
    SetupWindow4 " Example Green Fire App compiled by Furia \x00"
    ˙˙20 20˙ 0.9 0.9 600

    ˙˙˙ }
    also blocks may be instead of form {a,b,c,d,e} be a,b,c,d,e;

    so above may be

    void main
    ˙˙˙˙ SetSleepValue 5, SetScaleOnResize 0, Set3dDrawingMode 1,
    SetupWindow4 " Example Green Fire App compiled by Furia \x00"
    ˙˙20 20˙ 0.9 0.9 600 ;


    as fay as i remember (im not sure right now if function ending sign i
    chose as ";" "." ";." or smthe (possibly it need to be something like ;.
    but it yet is not decided


    or maybe it was ";;" as an end - probably this should be just some
    unicode sign as ending function definition denoter (even something like small/medium rectangle ) but im trying to go as far in this syntax
    thining and cleaning as far as i can go



    there also may be optional :

    void main: SetSleepValue 5, SetScaleOnResize 0, Set3dDrawingMode 1,
    SetupWindow4 " Example Green Fire App compiled by Furia \x00"
    ˙˙20 20˙ 0.9 0.9 600;

    i emen is optional if after definition header there is newline

    those things are somewhat clear (maybe this ending function if there
    is no {} is not cleer but other seem clear

    but many things are yet not resolved (like if statements or even im
    not sure as to assigments, for loops -s till not chosen


    but the bare naked form of function calls is imo impressive






    as forr my assigment ideas the last one i remember was

    _a 344

    thsi is initialisation

    a_ 3344

    this is assigment (maybe some unicode coud be chosen instead)

    _x you read "let x" so _x 6 is "let x 6"

    x_ y+3 //x=y+3


    but im not sure as to dis it looks quite dymanic but the problem is for floats/chars etc






    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From bart@3:633/10 to All on Thu Sep 10 14:33:02 2026
    On 10/09/2026 13:37, fir wrote:
    bart pisze:

    ˙˙public class HelloWorld {
    ˙˙˙˙ public static void main(String[] args) {
    ˙˙˙˙˙˙˙˙ System.out.println("Hello, World");
    ˙˙˙˙ }
    ˙˙}

    Whereas mine looks like so:

    ˙˙ proc main =
    ˙˙˙˙˙˙ println "Hello, World"
    ˙˙ end


    in c it would be

    main() printf("Hello, World");

    In C it would be:

    #include <stdio.h>

    int main(void) {
    printf("Hello, World\n");
    }

    From C23, you can get rid of the 'void' (you can do that now, but it
    has a different meaning).



    if they would allow skkip {}

    main() { printf("Hello, World"); }

    ˙in this short cases like it is in ifs

    in my proto-extended-c i compile˙ it is

    main { printf "Hello, World" }

    it is from this compiled example (this void i should remove some way
    but it was under work and im not touching it recently)

    ˙void ProcessMouseMove mouse_x mouse_y { }

    C generally has too much punctuation, but you can also have too little!

    Your example doesn't specify parameter types for example. With those in
    place, then you can have syntax that looks like:

    A B C D E F {}

    A is the return type (a user-defined type); B is the function name; D is
    a parameter of type C; and F is a parameter of type F. There is little structure.

    Further, if this is a function all:

    F G H I J

    Then you don't know if this means F(G, H, I, J), or F (G, H(I), J) etc.

    Some languages manage it but it needs very careful design and a set of
    rules.



    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From fir@3:633/10 to All on Thu Sep 10 15:51:00 2026
    bart pisze:
    On 10/09/2026 13:37, fir wrote:
    bart pisze:

    ˙˙public class HelloWorld {
    ˙˙˙˙ public static void main(String[] args) {
    ˙˙˙˙˙˙˙˙ System.out.println("Hello, World");
    ˙˙˙˙ }
    ˙˙}

    Whereas mine looks like so:

    ˙˙ proc main =
    ˙˙˙˙˙˙ println "Hello, World"
    ˙˙ end


    in c it would be

    main() printf("Hello, World");

    In C it would be:

    ˙˙ #include <stdio.h>

    ˙˙ int main(void) {
    ˙˙˙˙˙ printf("Hello, World\n");
    ˙˙ }

    From C23, you can get rid of the 'void' (you can do that now, but it
    has a different meaning).



    if they would allow skkip {}

    main() { printf("Hello, World"); }

    ˙˙in this short cases like it is in ifs

    in my proto-extended-c i compile˙ it is

    main { printf "Hello, World" }

    it is from this compiled example (this void i should remove some way
    but it was under work and im not touching it recently)

    ˙˙void ProcessMouseMove mouse_x mouse_y { }

    C generally has too much punctuation, but you can also have too little!

    Your example doesn't specify parameter types for example. With those in place, then you can have syntax that looks like:

    ˙˙ A B C D E F {}

    A is the return type (a user-defined type); B is the function name; D is
    a parameter of type C; and F is a parameter of type F. There is little structure.



    well im still working on that (now having longer break) and
    yet i used only ints (so i quiess i should ay i work on new b not new c ;c)

    but as far as i remember the above in my case would be

    A B C D E F {}

    A is a function name and B C D E F are ints (so you see its rather clear)


    it would not compile in my compiler ("furia") as i need this first
    keyword to denote global definitioons


    BTW i compiled also such examples (it compilers and works afair but is
    still undef construction so its under future changes)


    def ProcessMouseMove mouse_x mouse_y.

    def foo z1 z2 z3 z4:
    printf " %d %d %d %d \x00" z1 z2 z3 z4.

    def AddBackgrounColor zzz
    x = rand2 1 2, background_color += x .

    def goo z1 z2 z3 -> z4 z5 z6
    {z4=z1+z2, z5=z2+z3, z6=z3+z1}


    def doo
    {a b c=goo 2 3 4, printf " a %d b %d c %d \x00" a b c }


    it was before my later conclusions to not use = as assigment

    and alos my recent ones (not yet tested) to use what i call "hypothesis"
    as an if without any sign

    def main
    {
    _x 3

    x>2 print "x is above 2"
    x>2 print "x is above 2"
    x>2 { print "x is above 2" }
    }












    Further, if this is a function all:

    ˙˙ F G H I J

    Then you don't know if this means F(G, H, I, J), or F (G, H(I), J) etc.

    Some languages manage it but it needs very careful design and a set of rules.




    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From fir@3:633/10 to All on Thu Sep 10 16:03:04 2026
    bart pisze:
    Further, if this is a function all:

    ˙˙ F G H I J

    Then you don't know if this means F(G, H, I, J), or F (G, H(I), J) etc.

    this is not a problem in my bare-naked forms tuday as

    it would be

    F G (H I) J

    then you see F is function all that takes 3 args and H is a function
    call that takes one

    so this seem totally no problem, but types in headers what you mention
    earlier is a problem..but for now as i sait i only work on "new B"

    who knows mayne i should call this language as B i know there is a
    language b but maybe it is lowercase ba and i could use bigcase B ;c

    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From bart@3:633/10 to All on Thu Sep 10 15:27:25 2026
    On 10/09/2026 15:03, fir wrote:
    bart pisze:
    Further, if this is a function all:

    ˙˙˙ F G H I J

    Then you don't know if this means F(G, H, I, J), or F (G, H(I), J) etc.

    this is not a problem in my bare-naked forms tuday as

    it would be

    ˙ F G (H I) J

    then you see F is function all that takes 3 args and H is a function
    call that takes one

    That makes it too strict. C has variadic functions. Some languages have optional arguments with default values. Some languages are dynamically
    types so you don't know at compile-time (and the reader can't tell) how
    many arguments F takes.

    so this seem totally no problem,

    Try it with a real example, such as:

    succeeded = tdefl_init pComp pPut_buf_func pPut_buf_user flags
    == TDEFL_STATUS_OKAY ;

    succeeded = succeeded && tdefl_compress_buffer pComp pBuf
    buf_len TDEFL_FINISH == TDEFL_STATUS_DONE

    These have had parentheses and commas removed. There is also this:

    F G H I + J

    Even if you know that F takes two arguments, and H takes one, which of
    these is the intended meaning:

    F(G, H(I) + J)
    F(G, H(I)) + J



    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From fir@3:633/10 to All on Thu Sep 10 16:41:58 2026
    fir pisze:
    bart pisze:
    Further, if this is a function all:

    ˙˙˙ F G H I J

    Then you don't know if this means F(G, H, I, J), or F (G, H(I), J) etc.

    this is not a problem in my bare-naked forms tuday as

    it would be

    ˙ F G (H I) J

    then you see F is function all that takes 3 args and H is a function
    call that takes one

    so this seem totally no problem, but types in headers what you mention earlier is a problem..but for now as i sait i only work on "new B"

    who knows mayne i should call this language as B i know there is a
    language b but maybe it is lowercase ba and i could use bigcase B ;c



    so on summery such type codes

    def main { a k g (j 3 3 ), h n 23 , t , G , d f gg u }


    are totally clear
    you may put expressions (but no hypothesis) and assigments here i guess

    by expressions i mean things like a*b/3-h by hypothesis a<4*7 i mean expressions give arithmetic values and hypthesis logical

    amd yet initialisations

    _k _j _y _e _gg _u

    def main{a k_7 g (j 3*y v_3*9 ),h _n 23,t,G,d(_f 6) gg u}

    [it is like c


    int k,j,y,e,gg,u;
    main{a(k=7,g,j(3*y,v=3*9),h(int n=23),t(),G(),d(int f=6,gg,u);}



    its allso is probbaly totally clear (looks like mes but those unicode
    signs for initialisation _f and assigment f_ could be added, it seem
    that they maybe should be shorter)

    in fact i probably add also hypothesis branches but im not yet quite
    sure as them and has also not yet else syntax


    if taking ! as else sign may add yet
    like G>9 H!s

    which is G>9?H:s or G()<9? H():s(); if G H s are functions


    _k _j _y _e _gg _u

    def main{a k_7 g (j 3*y v_3*9 ),h _n 23,t,G<9 H!s ,d(_f 6) gg u}


    with some other unicode operator

    ?k ?j ?y ?e ?gg ?u

    def main{a k?7 g (j 3*y v?3*9 ),h ?n 23,t,G<9 H!s ,d(?f 6) gg u}









    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From fir@3:633/10 to All on Thu Sep 10 16:45:50 2026
    bart pisze:
    On 10/09/2026 15:03, fir wrote:
    bart pisze:
    Further, if this is a function all:

    ˙˙˙ F G H I J

    Then you don't know if this means F(G, H, I, J), or F (G, H(I), J) etc.

    this is not a problem in my bare-naked forms tuday as

    it would be

    ˙˙ F G (H I) J

    then you see F is function all that takes 3 args and H is a function
    call that takes one

    That makes it too strict. C has variadic functions. Some languages have optional arguments with default values. Some languages are dynamically
    types so you don't know at compile-time (and the reader can't tell) how
    many arguments F takes.

    so this seem totally no problem,

    Try it with a real example, such as:

    ˙˙˙ succeeded =˙ tdefl_init pComp˙ pPut_buf_func˙ pPut_buf_user˙ flags
    == TDEFL_STATUS_OKAY ;

    ˙˙˙ succeeded = succeeded &&˙ tdefl_compress_buffer pComp˙ pBuf
    buf_len˙ TDEFL_FINISH == TDEFL_STATUS_DONE

    These have had parentheses and commas removed. There is also this:

    ˙˙˙˙ F G H I + J

    Even if you know that F takes two arguments, and H takes one, which of
    these is the intended meaning:

    ˙˙˙˙ F(G, H(I) + J)
    ˙˙˙˙ F(G, H(I)) + J


    i not quite understand yopu you simply has

    a b c d e f

    you know a is a function and rest is arguments

    it make no rpoblem with variadic


    a b (c d) e f

    hetre both a and c may be variadic, you may add extra arguments

    a b (c d 1 2) e f 3 4











    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From fir@3:633/10 to All on Thu Sep 10 16:47:04 2026
    bart pisze:
    These have had parentheses and commas removed. There is also this:

    ˙˙˙˙ F G H I + J

    Even if you know that F takes two arguments, and H takes one, which of
    these is the intended meaning:

    ˙˙˙˙ F(G, H(I) + J)
    ˙˙˙˙ F(G, H(I)) + J



    F G H I + J

    this above s function f that takes 3 arguments G H and I+J



    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From fir@3:633/10 to All on Thu Sep 10 16:54:32 2026
    fir pisze:
    bart pisze:
    These have had parentheses and commas removed. There is also this:

    ˙˙˙˙˙ F G H I + J

    Even if you know that F takes two arguments, and H takes one, which of
    these is the intended meaning:

    ˙˙˙˙˙ F(G, H(I) + J)
    ˙˙˙˙˙ F(G, H(I)) + J



    F G H I + J

    this above s function f that takes 3 arguments G H and I+J


    ypu got

    function arg arg arg arg arg

    (always..at least if the first one is function name, if it is something another maybe i will change it but as for now it seems its always a
    function, it cant be int as int would be

    _g (initialisation) or g_ (assigment)

    so d jkd d d lkjd djl is always faaaaa type (here it would not compile i guess)


    so if you got a s d (g d f b) j k it is faa(faaa)aa and so on





    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From fir@3:633/10 to All on Thu Sep 10 16:59:24 2026
    fir pisze:
    Try it with a real example, such as:

    ˙˙˙˙ succeeded =˙ tdefl_init pComp˙ pPut_buf_func˙ pPut_buf_user˙ flags
    == TDEFL_STATUS_OKAY ;

    ˙˙˙˙ succeeded = succeeded &&˙ tdefl_compress_buffer pComp˙ pBuf
    buf_len˙ TDEFL_FINISH == TDEFL_STATUS_DONE


    im not sure what you mean hera bove but with this e conventions im
    talkin abouts its

    succeeded = tdefl_init( pComp, pPut_buf_func, pPut_buf_user, flags== TDEFL_STATUS_OKAY) ;

    and

    succeeded = succeeded && tdefl_compress_buffer( pComp , pBuf, buf_len, TDEFL_FINISH == TDEFL_STATUS_DONE);





    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From fir@3:633/10 to All on Thu Sep 10 17:06:26 2026
    fir pisze:
    fir pisze:
    bart pisze:
    These have had parentheses and commas removed. There is also this:

    ˙˙˙˙˙ F G H I + J

    Even if you know that F takes two arguments, and H takes one, which
    of these is the intended meaning:

    ˙˙˙˙˙ F(G, H(I) + J)
    ˙˙˙˙˙ F(G, H(I)) + J



    F G H I + J

    this above s function f that takes 3 arguments G H and I+J


    ypu got

    function arg arg arg arg arg

    (always..at least if the first one is function name, if it is something another˙ maybe i will change it but as for now it seems its always a function, it cant be int as int would be

    _g (initialisation) or g_ (assigment)

    so d jkd d d lkjd djl is always faaaaa type (here it would not compile i guess)


    so if you got a s d (g d f b) j k˙ it is faa(faaa)aa and so on







    i got kinda more troubles with function returning more values than 1
    (as i want to have it)

    now i consider

    _x_y foo 2 3 4 // (int x, int y) = foo(2,3,4)

    x_ _y foo 3 4 5 // (x, int y) = foo(2,3,4)






    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From fir@3:633/10 to All on Thu Sep 10 17:15:07 2026
    fir pisze:
    fir pisze:
    fir pisze:
    bart pisze:
    These have had parentheses and commas removed. There is also this:

    ˙˙˙˙˙ F G H I + J

    Even if you know that F takes two arguments, and H takes one, which
    of these is the intended meaning:

    ˙˙˙˙˙ F(G, H(I) + J)
    ˙˙˙˙˙ F(G, H(I)) + J



    F G H I + J

    this above s function f that takes 3 arguments G H and I+J


    ypu got

    function arg arg arg arg arg

    (always..at least if the first one is function name, if it is
    something another˙ maybe i will change it but as for now it seems its
    always a function, it cant be int as int would be

    _g (initialisation) or g_ (assigment)

    so d jkd d d lkjd djl is always faaaaa type (here it would not compile
    i guess)


    so if you got a s d (g d f b) j k˙ it is faa(faaa)aa and so on







    i got kinda more troubles with function returning more values than 1
    (as i want to have it)

    now i consider

    _x_y foo 2 3 4 // (int x, int y) = foo(2,3,4)

    x_ _y foo 3 4 5 // (x,˙ int y) = foo(2,3,4)


    this above would need some decisions as the meaning of above would
    have different meaning if foo returns onlu 1 value

    like

    x_ _y f //sets x y if foo returns 2 values

    x_ _y f // may be x= (int y = f() ) if f returns one and it is a
    question what allow whad disallow and so on,

    but this pure naked normal form "d e r g :' is rather totally clear




    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From bart@3:633/10 to All on Thu Sep 10 16:57:17 2026
    On 10/09/2026 15:59, fir wrote:
    fir pisze:
    Try it with a real example, such as:

    ˙˙˙˙˙ succeeded =˙ tdefl_init pComp˙ pPut_buf_func˙ pPut_buf_user
    flags == TDEFL_STATUS_OKAY ;

    ˙˙˙˙˙ succeeded = succeeded &&˙ tdefl_compress_buffer pComp˙ pBuf
    buf_len˙ TDEFL_FINISH == TDEFL_STATUS_DONE


    im not sure what you mean hera bove but with this e conventions im
    talkin abouts its

    succeeded =˙ tdefl_init( pComp,˙ pPut_buf_func,˙ pPut_buf_user,˙ flags== TDEFL_STATUS_OKAY) ;

    Not bad, but this is the original:

    succeeded = (tdefl_init(pComp, pPut_buf_func, pPut_buf_user, flags)
    == TDEFL_STATUS_OKAY);


    and

    succeeded = succeeded &&˙ tdefl_compress_buffer( pComp , pBuf, buf_len, TDEFL_FINISH == TDEFL_STATUS_DONE);
    And here's the original for this:

    succeeded = succeeded && (tdefl_compress_buffer(pComp, pBuf,
    buf_len, TDEFL_FINISH) == TDEFL_STATUS_DONE);


    I think the parentheses and commas do a good job in removing ambiguity.

    Although the originals probably had one pair of superfluous parentheses
    each, as '=='s precedence is already higher than both = and &&.

    But, what are you planning with general expressions: will you still have operator precedences?

    --- 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 Thu Sep 10 18:10:59 2026
    On 10/09/2026 17:15, fir wrote:
    fir pisze:

    i got kinda more troubles with function returning more values than 1
    (as i want to have it)

    now i consider

    _x_y foo 2 3 4 // (int x, int y) = foo(2,3,4)

    x_ _y foo 3 4 5 // (x,˙ int y) = foo(2,3,4)


    this above would need some decisions as the meaning of above would
    have different meaning if foo returns onlu 1 value

    like

    x_ _y f //sets x y if foo returns 2 values

    x_ _y f // may be˙ x= (int y = f() ) if f returns one and it is a
    question what allow whad disallow and so on,

    but this pure naked normal form "d e r g :' is rather totally clear




    This is all getting /very/ far from C. Might it be a good time to start
    a new thread in comp.lang.misc instead?

    If you are serious about making his own language in some way, then I am
    sure he would benefit from paying some attention to Bart's advice (I
    might not like his language, or have any use of it, but there's no doubt
    he has more experience than most in language design).

    And maybe in comp.lang.misc the thread will attract others that have
    interest in new languages, or advice based on different language experience.





    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From fir@3:633/10 to All on Thu Sep 10 18:18:19 2026
    bart pisze:
    On 10/09/2026 15:59, fir wrote:
    fir pisze:
    Try it with a real example, such as:

    ˙˙˙˙˙ succeeded =˙ tdefl_init pComp˙ pPut_buf_func˙ pPut_buf_user
    flags == TDEFL_STATUS_OKAY ;

    ˙˙˙˙˙ succeeded = succeeded &&˙ tdefl_compress_buffer pComp˙ pBuf
    buf_len˙ TDEFL_FINISH == TDEFL_STATUS_DONE


    im not sure what you mean hera bove but with this e conventions im
    talkin abouts its

    succeeded =˙ tdefl_init( pComp,˙ pPut_buf_func,˙ pPut_buf_user,
    flags== TDEFL_STATUS_OKAY) ;

    Not bad, but this is the original:

    ˙ succeeded = (tdefl_init(pComp, pPut_buf_func, pPut_buf_user, flags)
    == TDEFL_STATUS_OKAY);


    thet would be

    succeeded = (tdefl_init pComp pPut_buf_func pPut_buf_user flags ) == TDEFL_STATUS_OKAY




    and

    succeeded = succeeded &&˙ tdefl_compress_buffer( pComp , pBuf,
    buf_len, TDEFL_FINISH == TDEFL_STATUS_DONE);
    And here's the original for this:

    ˙˙˙ succeeded = succeeded && (tdefl_compress_buffer(pComp, pBuf,
    buf_len, TDEFL_FINISH) == TDEFL_STATUS_DONE);


    I think the parentheses and commas do a good job in removing ambiguity.

    Although the originals probably had one pair of superfluous parentheses each, as '=='s precedence is already higher than both = and &&.

    But, what are you planning with general expressions: will you still have operator precedences?


    if the comma and parenthesis are not needed why use them

    esp as a most amount of code is like

    void RunFrame advance
    {
    Initialise,
    ClearFrameData 0x444444
    DrawLine3d 100.0 100.0 0.0 100.0 -100.0 0.0 0xffffff
    DrawLine3d 100.0 -100.0 0.0 -100.0 -100.0 0.0 0xffffff
    DrawLine3d -100.0 -100.0 0.0 -100.0 100.0 0.0 0xffffff
    DrawLine3d -100.0 100.0 0.0 100.0 100.0 0.0 0xffffff
    DrawDot3d 0.0 0.0 100.0 20.0 0x557788
    DrawDot3d 0.0 0.0 150.0 30.0 0x557722
    DrawDot3d 0.0 0.0 -100.0 10.0 0xaa7788
    InitSomeJointsFigures
    DrawCloud1, DrawCloud2,
    DrawCloud11, DrawCloud12, UpdateDotsBag, DrawDotsBag

    FillRectangle2 10 10 20 20 color
    DrawSomeText2F 0xcccccc 0x666666 20 10 " %x \x00" 0xffffff
    DrawSomeText2F 0xcccccc 0x666666 10 20 "hello, this is example
    program compiled by fir's furia compiler \x00"

    DeawLines
    DrawTextByBalls "hello\x00" 0 0 0x999999
    DrawCubesCubeGeo

    BezierPatchTest

    space_pressed? FireDotFromCameraCurrentColor 0.0 0.0 100000 20
    a_pressed?! FireDotFromCameraCurrentColor 1.0 0.0 10000 20
    f5_toggler? DrawManual

    DrawFloor 20000 30 0x555555
    DrawRawModel

    }

    i mean lot are "normal" simple calls and there is a lot of (,,,,);
    to skip
    as to operator precedence ofc its needed and as i said what i show
    here is the part that is "resolved" but there are more complex
    cases where it is not resolved yet

    (for example for this many return values , operator form of functions
    (as a would like to have "x foo y" where foo is a function and x y are arguments, and those float char types, some constructions like loops
    and so on


    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From fir@3:633/10 to All on Thu Sep 10 18:21:19 2026
    David Brown pisze:
    On 10/09/2026 17:15, fir wrote:
    fir pisze:

    i got kinda more troubles with function returning more values than 1
    (as i want to have it)

    now i consider

    _x_y foo 2 3 4 // (int x, int y) = foo(2,3,4)

    x_ _y foo 3 4 5 // (x,˙ int y) = foo(2,3,4)


    this above would need some decisions as the meaning of above would
    have different meaning if foo returns onlu 1 value

    like

    x_ _y f //sets x y if foo returns 2 values

    x_ _y f // may be˙ x= (int y = f() ) if f returns one and it is a
    question what allow whad disallow and so on,

    but this pure naked normal form "d e r g :' is rather totally clear




    This is all getting /very/ far from C.˙ Might it be a good time to start
    a new thread in comp.lang.misc instead?

    If you are serious about making his own language in some way, then I am
    sure he would benefit from paying some attention to Bart's advice (I
    might not like his language, or have any use of it, but there's no doubt
    he has more experience than most in language design).

    And maybe in comp.lang.misc the thread will attract others that have interest in new languages, or advice based on different language
    experience.

    this is theoretical c imo - c has some set of ideas internally and is
    "made" from this ideas so exploring those ideas ic C imo but more
    theoretical

    i make some theory and some of it is more general (like say this last
    things that objects are indeed knots/webs, or code jumping problem)but
    its also a c if it uses c


    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From fir@3:633/10 to All on Thu Sep 10 18:35:57 2026
    fir pisze:
    Janis Papanagnou pisze:
    On 2026-09-10 00:52, Keith Thompson wrote:
    Janis Papanagnou <janis_papanagnou+ng@hotmail.com> writes:
    [...]
    (Please, for the sake of the people that haven't killfiled you, use an >>>> online-translator to create comprehensible texts! - In case that your
    native language *is* English I suggest to translate your text to some
    other language and then back to English; the translators are obviously >>>> good enough to fix your language or writing problems in that process.)

    The above was addressed to "fir". [...]

    Yes.

    [ background info snipped ]

    I suggest that one more attempt to get fir to write clearly is
    unlikely to be effective.˙ I've solved the problem for myself by
    adding him to my killfile.

    Thanks for the the info and warning. - Actually he is already in my
    killfile, so I see his writings only when he gets quoted my someone.

    Janis


    welcome in keith team ;c

    anti-fir Keith's Team of funny asses



    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From fir@3:633/10 to All on Thu Sep 10 18:36:59 2026
    fir pisze:
    fir pisze:
    Janis Papanagnou pisze:
    On 2026-09-10 00:52, Keith Thompson wrote:
    Janis Papanagnou <janis_papanagnou+ng@hotmail.com> writes:
    [...]
    (Please, for the sake of the people that haven't killfiled you, use an >>>>> online-translator to create comprehensible texts! - In case that your >>>>> native language *is* English I suggest to translate your text to some >>>>> other language and then back to English; the translators are obviously >>>>> good enough to fix your language or writing problems in that process.) >>>>
    The above was addressed to "fir". [...]

    Yes.

    [ background info snipped ]

    I suggest that one more attempt to get fir to write clearly is
    unlikely to be effective.˙ I've solved the problem for myself by
    adding him to my killfile.

    Thanks for the the info and warning. - Actually he is already in my
    killfile, so I see his writings only when he gets quoted my someone.

    Janis


    welcome in keith team ;c

    anti-fir Keith's Team of funny asses

    (joking)

    --- 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 Thu Sep 10 18:45:52 2026
    On 10/09/2026 18:21, fir wrote:
    David Brown pisze:


    This is all getting /very/ far from C.˙ Might it be a good time to
    start a new thread in comp.lang.misc instead?

    If you are serious about making his own language in some way, then I
    am sure he would benefit from paying some attention to Bart's advice
    (I might not like his language, or have any use of it, but there's no
    doubt he has more experience than most in language design).

    And maybe in comp.lang.misc the thread will attract others that have
    interest in new languages, or advice based on different language
    experience.

    this is theoretical c imo - c has some set of ideas internally and is
    "made" from this ideas so exploring those ideas ic C imo but more theoretical

    i make some theory and some of it is more general (like say this last
    things that objects are indeed knots/webs, or code jumping problem)but
    its also a c if it uses c


    No, it is not C. You might have started off thinking about small
    changes to C, but you are now talking about something completely different.

    Either this is just a waste of time (and the fact that most of your
    posts are replies to your own posts suggest that this is the case), or
    you are really interested in making a new language - and comp.lang.misc
    would be a better place to discuss it.


    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From fir@3:633/10 to All on Thu Sep 10 18:56:30 2026
    David Brown pisze:
    On 10/09/2026 18:21, fir wrote:
    David Brown pisze:


    This is all getting /very/ far from C.˙ Might it be a good time to
    start a new thread in comp.lang.misc instead?

    If you are serious about making his own language in some way, then I
    am sure he would benefit from paying some attention to Bart's advice
    (I might not like his language, or have any use of it, but there's no
    doubt he has more experience than most in language design).

    And maybe in comp.lang.misc the thread will attract others that have
    interest in new languages, or advice based on different language
    experience.

    this is theoretical c imo - c has some set of ideas internally and is
    "made" from this ideas so exploring those ideas ic C imo but more
    theoretical

    i make some theory and some of it is more general (like say this last
    things that objects are indeed knots/webs, or code jumping problem)but
    its also a c if it uses c


    No, it is not C.˙ You might have started off thinking about small
    changes to C, but you are now talking about something completely different.

    Either this is just a waste of time (and the fact that most of your
    posts are replies to your own posts suggest that this is the case), or
    you are really interested in making a new language - and comp.lang.misc would be a better place to discuss it.


    it is but you dont understand it becouse you have shallow view on c

    in this context c is like an iceberg it has its surface (i call it skin)
    but it has the rationale and deep design decisions under the water
    surface level... so if i prove for example that c typical "skin"
    (i call it gothic (at least those part around(,,,,); )

    san be changed form

    foo(a,b, "text",c);

    into

    foo a b "text" c

    it is/are thesis on c not on different anguage - they are about
    c consciousnes and about potential sjkin changes (and are also about new
    skinn too, thats right)




    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From fir@3:633/10 to All on Thu Sep 10 19:01:23 2026
    fir pisze:
    David Brown pisze:
    On 10/09/2026 18:21, fir wrote:
    David Brown pisze:


    This is all getting /very/ far from C.˙ Might it be a good time to
    start a new thread in comp.lang.misc instead?

    If you are serious about making his own language in some way, then I
    am sure he would benefit from paying some attention to Bart's advice
    (I might not like his language, or have any use of it, but there's
    no doubt he has more experience than most in language design).

    And maybe in comp.lang.misc the thread will attract others that have
    interest in new languages, or advice based on different language
    experience.

    this is theoretical c imo - c has some set of ideas internally and is
    "made" from this ideas so exploring those ideas ic C imo but more
    theoretical

    i make some theory and some of it is more general (like say this last
    things that objects are indeed knots/webs, or code jumping problem)but
    its also a c if it uses c


    No, it is not C.˙ You might have started off thinking about small
    changes to C, but you are now talking about something completely
    different.

    Either this is just a waste of time (and the fact that most of your
    posts are replies to your own posts suggest that this is the case), or
    you are really interested in making a new language - and
    comp.lang.misc would be a better place to discuss it.


    it is but you dont understand it becouse you have shallow view on c

    in this context c is like an iceberg it has its surface (i call it skin)
    but it has the rationale and deep design decisions under the water
    surface level... so if i prove for example that c typical "skin"
    (i call it gothic (at least those part around(,,,,);˙ )

    san be changed form

    foo(a,b, "text",c);

    into

    foo a b "text" c

    it is/are thesis on c not on different anguage - they are about
    c consciousnes and about potential sjkin changes (and are also about new skinn too, thats right)

    if so some could sa y well if so then takin about all languages
    different than c could be considered as taking on c but i see it different

    its about a thing that if you will take some arbitary bad changes this
    make another alanguage but if youre keeping to this inner c right spirit
    and being scentific in this decisions on it then it is ima on inner
    side/part of c

    and those people whi see c as only its surfaces are medicores

    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From fir@3:633/10 to All on Thu Sep 10 19:17:33 2026
    David Brown pisze:
    On 10/09/2026 18:21, fir wrote:
    David Brown pisze:


    Either this is just a waste of time (and the fact that most of your
    posts are replies to your own posts suggest that this is the case), or
    you are really interested in making a new language - and comp.lang.misc would be a better place to discuss it.



    how it suggest that? note thise are 'replies' maybe in some technical
    sense of a usenet reader..but on thought /write level they are just continuation of thoughts/topic..its rather quite artificall to write ll
    you got to say in one post and assume you have nothing to add ..i often
    have things to add

    im also this type fellow who dont like to spend time boring. so im
    rather active in some places i go for some thime but this also makes
    weariness so - dont worry if something worries - when i get weary and exhausted form ideas in given time i will take break (possibly for weeks months of not years) ;c

    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From fir@3:633/10 to All on Thu Sep 10 19:20:18 2026
    fir pisze:
    David Brown pisze:
    On 10/09/2026 18:21, fir wrote:
    David Brown pisze:


    This is all getting /very/ far from C.˙ Might it be a good time to
    start a new thread in comp.lang.misc instead?

    If you are serious about making his own language in some way, then I
    am sure he would benefit from paying some attention to Bart's advice
    (I might not like his language, or have any use of it, but there's
    no doubt he has more experience than most in language design).

    And maybe in comp.lang.misc the thread will attract others that have
    interest in new languages, or advice based on different language
    experience.

    this is theoretical c imo - c has some set of ideas internally and is
    "made" from this ideas so exploring those ideas ic C imo but more
    theoretical

    i make some theory and some of it is more general (like say this last
    things that objects are indeed knots/webs, or code jumping problem)but
    its also a c if it uses c


    No, it is not C.˙ You might have started off thinking about small
    changes to C, but you are now talking about something completely
    different.

    Either this is just a waste of time (and the fact that most of your
    posts are replies to your own posts suggest that this is the case), or
    you are really interested in making a new language - and
    comp.lang.misc would be a better place to discuss it.


    it is but you dont understand it becouse you have shallow view on c

    in this context c is like an iceberg it has its surface (i call it skin)
    but it has the rationale and deep design decisions under the water
    surface level... so if i prove for example that c typical "skin"
    (i call it gothic (at least those part around(,,,,);˙ )

    san be changed form

    foo(a,b, "text",c);

    into

    foo a b "text" c

    it is/are thesis on c not on different anguage - they are about
    c consciousnes and about potential sjkin changes (and are also about new skinn too, thats right)



    i could agree that some considerations and examples when im
    searching for good syntax those nut used pieces of syntax are not c
    but final scientific conclusions imo are (and that some parts are not,
    well they some kind necessary syntax foam - but they lead to more
    c grounded conclusions)

    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From fir@3:633/10 to All on Thu Sep 10 20:19:36 2026
    fir pisze:
    David Brown pisze:
    On 10/09/2026 18:21, fir wrote:
    David Brown pisze:


    This is all getting /very/ far from C.˙ Might it be a good time to
    start a new thread in comp.lang.misc instead?

    If you are serious about making his own language in some way, then I
    am sure he would benefit from paying some attention to Bart's advice
    (I might not like his language, or have any use of it, but there's
    no doubt he has more experience than most in language design).

    And maybe in comp.lang.misc the thread will attract others that have
    interest in new languages, or advice based on different language
    experience.

    this is theoretical c imo - c has some set of ideas internally and is
    "made" from this ideas so exploring those ideas ic C imo but more
    theoretical

    i make some theory and some of it is more general (like say this last
    things that objects are indeed knots/webs, or code jumping problem)but
    its also a c if it uses c


    No, it is not C.˙ You might have started off thinking about small
    changes to C, but you are now talking about something completely
    different.

    Either this is just a waste of time (and the fact that most of your
    posts are replies to your own posts suggest that this is the case), or
    you are really interested in making a new language - and
    comp.lang.misc would be a better place to discuss it.


    it is but you dont understand it becouse you have shallow view on c

    in this context c is like an iceberg it has its surface (i call it skin)
    but it has the rationale and deep design decisions under the water
    surface level... so if i prove for example that c typical "skin"
    (i call it gothic (at least those part around(,,,,);˙ )

    san be changed form

    foo(a,b, "text",c);

    into

    foo a b "text" c

    it is/are thesis on c not on different anguage - they are about
    c consciousnes and about potential sjkin changes (and are also about new skinn too, thats right)




    you also my not damn know how hard it is

    in c i make i would say two work - one s those 'semantic' (?) ideas
    (liek one core of cpu on assembly level seing state of other core
    for example..great idea of makin cpu's and assembly great again ;c
    (potentially as im not sure how it would work))

    but i also do this skin work and this skin work is hard

    for example ide of

    _x 640
    _y 480

    as a syntax for int declarations seem neat
    but when considered in expressions like

    foo _x 640 _y 480

    (which is foo(int x =640, int y = 480);

    seems problematic becouse in eye it may look more like foo
    takes 4 args etc)

    such thing as

    foo x'640 y'480

    where ' can be replaced by some unicode

    would spare 2 spaces

    so maybe

    x'640
    y'480

    is better as initialisation - but it in turn looks less neat

    yet all this mus be compatible with all other syntaxes or maybe
    i should say COMPATIBLE WITH ALL other syntaxes

    so its hard work that should be valued - its not a trash
    (compared to what soem othar people in languages do do they
    make often trash - they design decision are flawedon first flawed step
    so where they go in 100th step? (nowhere as they will not go )






    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From fir@3:633/10 to All on Thu Sep 10 20:25:17 2026
    fir pisze:
    fir pisze:
    David Brown pisze:
    On 10/09/2026 18:21, fir wrote:
    David Brown pisze:


    This is all getting /very/ far from C.˙ Might it be a good time to
    start a new thread in comp.lang.misc instead?

    If you are serious about making his own language in some way, then
    I am sure he would benefit from paying some attention to Bart's
    advice (I might not like his language, or have any use of it, but
    there's no doubt he has more experience than most in language design). >>>>>
    And maybe in comp.lang.misc the thread will attract others that
    have interest in new languages, or advice based on different
    language experience.

    this is theoretical c imo - c has some set of ideas internally and is
    "made" from this ideas so exploring those ideas ic C imo but more
    theoretical

    i make some theory and some of it is more general (like say this
    last things that objects are indeed knots/webs, or code jumping
    problem)but
    its also a c if it uses c


    No, it is not C.˙ You might have started off thinking about small
    changes to C, but you are now talking about something completely
    different.

    Either this is just a waste of time (and the fact that most of your
    posts are replies to your own posts suggest that this is the case),
    or you are really interested in making a new language - and
    comp.lang.misc would be a better place to discuss it.


    it is but you dont understand it becouse you have shallow view on c

    in this context c is like an iceberg it has its surface (i call it
    skin) but it has the rationale and deep design decisions under the
    water surface level... so if i prove for example that c typical "skin"
    (i call it gothic (at least those part around(,,,,);˙ )

    san be changed form

    foo(a,b, "text",c);

    into

    foo a b "text" c

    it is/are thesis on c not on different anguage - they are about
    c consciousnes and about potential sjkin changes (and are also about
    new skinn too, thats right)




    you also my not damn know how hard it is

    in c i make i would say two work - one s those 'semantic' (?) ideas
    (liek one core of cpu on assembly level seing state of other core
    for example..great idea of makin cpu's and assembly great again ;c (potentially as im not sure how it would work))

    but i also do this skin work and this skin work is hard

    for example ide of

    _x 640
    _y 480

    as a syntax for int declarations seem neat
    but when considered in expressions like

    foo _x 640 _y 480

    (which is foo(int x =640, int y = 480);

    seems problematic becouse in eye it may look more like foo
    takes 4 args etc)

    such thing as

    foo x'640 y'480

    where ' can be replaced by some unicode

    would spare 2 spaces

    so maybe

    x'640
    y'480

    is better as initialisation - but it in turn looks less neat

    yet all this mus be compatible with all other syntaxes or maybe
    i should say COMPATIBLE WITH ALL other syntaxes

    MORE WORSE " they sometimes need to be compatible witn new underlying
    semantics becouse flaws in present semantics may make things hard of
    flaws in present semantics may make solutions break when new semantics
    would show better

    (so it is real hard searching here..sad its not valued to much by some
    shallow minds (if it is not valued))


    so its hard work that should be valued - its not a trash
    (compared to what soem othar people in languages do do they
    make often trash - they design decision are flawedon first flawed step
    so where they go in 100th step? (nowhere as they will not go )







    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From fir@3:633/10 to All on Thu Sep 10 21:02:26 2026
    fir pisze:


    so if you got a s d (g d f b) j k

    it is faa(faaa)aa and so on



    so here it is simple as i said if firs thing is function
    then all that things are "faa(fa)aa(faa)aaa" type

    buy i also consider more powerfull

    "aafaaa" thing

    like

    "ala" cat "bala"

    //cat("ala", "bala")

    this makes more problems but it has more power

    would be harder to reed for exampla

    foo a b cat d e g

    but whwn using meaningfull names it should probably be ok, may also use conventions like naming functions big case and variables lowcase, also
    anyone can use ()


    Foo a b Cat d e g

    still doder need what args of Cat are

    Foo a (b Cat d) e g

    yet there is also a problem of return values

    x_ Foo a (z_ b Cat d) e u_ g

    //same as above but also makes 3 assigns













    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From fir@3:633/10 to All on Thu Sep 10 21:59:26 2026
    fir pisze:
    fir pisze:


    so if you got a s d (g d f b) j k

    it is faa(faaa)aa and so on



    so here it is simple as i said if firs thing is function
    then all that things are "faa(fa)aa(faa)aaa" type

    buy i also consider more powerfull

    "aafaaa" thing

    like

    "ala" cat "bala"

    //cat("ala", "bala")

    this makes more problems but it has more power

    would be harder to reed for exampla

    ˙foo a b cat d e g

    but whwn using meaningfull names it should probably be ok, may also use conventions like naming functions big case and variables lowcase, also anyone can use ()


    Foo a b Cat d e g

    still doder need what args of Cat are

    Foo a (b Cat d) e g

    yet there is also a problem of return values

    x_ Foo a (z_ b Cat d) e u_ g

    //same as above but also makes 3 assigns





    i got also havy problem with function definitions header
    (in more general case) now i consider something like


    _average _delta y ?avg x
    {
    average_ (x+y)/2, delta_ abs(y-average)
    }

    ? is soem sign denoting definition

    its for

    int average, int delta (int y) avg (int x)
    {
    average = (x+y)/2; delta =abs(y-average)

    }

    not sure if it is good though, seems standable but if its good?




    --- 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 Thu Sep 10 14:08:01 2026
    On 9/9/2026 5:43 AM, David Brown wrote:
    [...]
    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.

    ________
    #ifndef __NUMBER_GENERATOR_H__
    #define __NUMBER_GENERATOR_H__ 1
    ________


    Is that __* non conformant? Does it breach the impl name prefix space?

    --- 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 Thu Sep 10 14:14:43 2026
    On 9/10/2026 2:08 PM, Chris M. Thomasson wrote:
    On 9/9/2026 5:43 AM, David Brown wrote:
    [...]
    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.

    ________
    #ifndef __NUMBER_GENERATOR_H__
    #define __NUMBER_GENERATOR_H__ 1
    ________


    Is that __* non conformant? Does it breach the impl name prefix space?

    Fwiw, my old code before I got hooked on #pragma once basically followed
    this pattern:

    /* Copyright 2005 Chris Thomasson */


    #ifndef AC_BASE_H
    #define AC_BASE_H


    #ifdef __cplusplus
    extern "C"
    {
    #endif




    /* attempt to determine the os type */
    #if defined ( linux ) || \
    defined ( __linux ) || \
    defined ( AC_BUILD_OS_FORCE_LINUX32 )

    #define AC_BUILD_OS_PTHREADS
    #define AC_BUILD_OS_LINUX

    #elif defined ( _WIN32 ) || \
    defined ( __TOS_WIN__ ) || \
    defined ( __WIN32__ ) || \
    defined ( WIN32 ) || \
    defined ( WIN64 ) || \
    defined ( _WIN32_WCE ) || \
    defined ( AC_BUILD_OS_FORCE_WIN32 ) || \
    defined ( AC_BUILD_OS_FORCE_WINCE )

    #if defined ( _WIN32_WCE ) || \
    defined ( AC_BUILD_OS_FORCE_WINCE )
    #define AC_BUILD_OS_WINDOWS_CE
    #endif
    #define AC_BUILD_OS_WINDOWS

    #ifdef WIN64
    #define AC_BUILD_OS_64_BIT
    #endif

    #elif defined ( AC_BUILD_OS_FORCE_PTHREAD )
    #define AC_BUILD_OS_PTHREADS

    #else
    #error AC_BUILD_OS - Windows or PThreads OS required!
    #endif




    /* attempt to determine the cpu type */
    #if defined ( _M_IX86 ) || \
    defined ( i386 ) || \
    defined ( __i386__ ) || \
    defined ( _X86_ ) || \
    defined ( AC_BUILD_CPU_FORCE_I686 )

    # define AC_CPU_X86

    # define AC_BUILD_32BIT

    # if defined ( AC_BUILD_OS_WINDOWS_CE ) || \
    defined ( AC_BUILD_CPU_FORCE_WINDOWS )

    # define AC_BUILD_CPU_WINDOWS

    #else

    # define AC_BUILD_CPU_I686

    #endif

    #elif defined ( _WIN32_WCE ) || \
    defined ( AC_BUILD_CPU_FORCE_WINDOWS )

    # define AC_BUILD_32BIT
    # define AC_BUILD_CPU_WINDOWS

    #else

    # error AC_BUILD_CPU - x86-32 or Windows required!

    #endif




    /***** Simple Compiler Abstraction *****/
    #ifdef _MSC_VER
    /* 4514: unreferenced inline function has been removed
    4710: function 'whatever' not inlined */
    # pragma warning ( disable : 4514 4710 )

    # define AC_INLINE_FORCE __forceinline
    # define AC_INLINE __inline

    # define AC_DECLSPEC_CALL_CDECL __cdecl
    # define AC_DECLSPEC_CALL_FAST_CALL __fastcall
    # define AC_DECLSPEC_CALL_STDCALL __stdcall

    # define AC_DECLSPEC_ALIGN( a ) __declspec ( align( a ) )
    # define AC_DECLSPEC_PACKED
    # define AC_DECLSPEC_MALLOC
    # define AC_DECLSPEC_UNUSED
    # define AC_DECLSPEC_NORET


    # if defined ( AC_BUILD_OS_UNDER_WINDOWS ) || \
    defined ( AC_BUILD_OS_WINDOWS )

    # define AC_DECLSPEC_API_IMPORT __declspec ( dllimport )
    # define AC_DECLSPEC_API_EXPORT __declspec ( dllexport )

    # endif




    #elif defined ( __GNUC__ )


    # define AC_INLINE_FORCE __attribute__ ( (always_inline) )
    # define AC_INLINE __inline__


    # ifdef AC_BUILD_CPU_I686

    # if defined ( AC_BUILD_OS_UNDER_WINDOWS ) || \
    defined ( AC_BUILD_OS_WINDOWS ) \

    # define AC_DECLSPEC_CALL_CDECL __attribute__ ( (cdecl) )
    # define AC_DECLSPEC_CALL_FAST_CALL __attribute__ ( (fastcall) )
    # define AC_DECLSPEC_CALL_STDCALL __attribute__ ( (stdcall) )

    # else

    # define AC_DECLSPEC_CALL_CDECL
    # define AC_DECLSPEC_CALL_FAST_CALL
    # define AC_DECLSPEC_CALL_STDCALL

    # endif

    # endif

    # define AC_DECLSPEC_ALIGN( a ) __attribute__ ( (aligned( a )) )
    # define AC_DECLSPEC_PACKED __attribute__ ( (packed) )
    # define AC_DECLSPEC_MALLOC __attribute__ ( (malloc) )
    # define AC_DECLSPEC_UNUSED __attribute__ ( (unused) )
    # define AC_DECLSPEC_NORET __attribute__ ( (noreturn) )


    # if defined ( AC_BUILD_OS_UNDER_WINDOWS ) || \
    defined ( AC_BUILD_OS_WINDOWS )\

    # define AC_DECLSPEC_API_IMPORT __attribute__ ( (dllimport) )
    # define AC_DECLSPEC_API_EXPORT __attribute__ ( (dllexport) )

    # else

    # define AC_DECLSPEC_CTOR __attribute__ ( (constructor) )
    # define AC_DECLSPEC_DTOR __attribute__ ( (destructor) )

    # endif

    #else
    # error AC_BUILD: MSVC++(6.0+) or GCC required!
    #endif


    #ifndef AC_DECLSPEC_API_IMPORT
    #define AC_DECLSPEC_API_IMPORT extern
    #endif


    #ifndef AC_DECLSPEC_API_EXPORT
    #define AC_DECLSPEC_API_EXPORT extern
    #endif


    #ifndef AC_DECLSPEC_CTOR
    #define AC_DECLSPEC_CTOR
    #endif


    #ifndef AC_DECLSPEC_DTOR
    #define AC_DECLSPEC_DTOR
    #endif


    #ifndef AC_UNUSED
    #define AC_UNUSED( ac_macro_state ) (void)ac_macro_state
    #endif


    #ifndef AC_DECLSPEC_INLINE
    #define AC_DECLSPEC_INLINE static AC_INLINE
    #endif


    #define AC_DECLSPEC_PACKED_ALIGN( ac_macro_align ) \
    AC_DECLSPEC_PACKED AC_DECLSPEC_ALIGN( ac_macro_align )


    #define AC_DECLSPEC_PACKED_ALIGN_CACHE_LINE \
    AC_DECLSPEC_PACKED AC_DECLSPEC_ALIGN_CACHE_LINE


    #define AC_BUILD_DBG_ASSERT( ac_macro_name, ac_macro_exp ) \
    struct AC_DECLSPEC_UNUSED \
    ac_build_dbg_## ac_macro_name ##_ \
    { \
    int test[( (ac_macro_exp) ) ? 1 : -1]; \
    }




    #ifdef __cplusplus
    }
    #endif


    #endif


    --- 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 Fri Sep 11 00:06:08 2026
    On 2026-09-10 09:48, David Brown wrote:
    On 10/09/2026 00:30, bart wrote:
    On 09/09/2026 22:26, Janis Papanagnou wrote:
    [...]
    [...]
    [...]

    Each type of import has its own advantages and disadvantages.

    Type 1 would need micro-management if you want a lot of symbols from a module.˙ But if you only need a small number, it can keep things neat -
    you only see what you actually want to use.˙ And if the imported module
    only really exports a single name (like "my_class.py" exporting
    "My_Class"), it's a neat solution that avoids later code clutter from
    having to specify the module name.

    Type 2 lets you immediately use all the identifiers from the module, but causes a lot of problems if things change in the future.˙ Maybe your own code has a function "fluff", and a later version of "foobar.py" also
    adds a function "fluff".˙ That is not going to be good.

    Type 3 lets you conveniently import all the exported symbols from the module, but you need to specify the namespace when using them.


    As I see it, Janis favours that kind of flexibility for modules (though
    of course the details may differ for different languages).

    Since you mentioned me - and since I don't intend after my thorough
    explanation to spend yet more time with bart's posts about it - let
    me confirm your interpretation, and give an example from practice.

    Note also that none of the languages I'm currently using is supporting
    that principle - there's no "best" language in that respect, although
    some are closer to an ideal modularization than others. (Some recent
    languages [that I don't know] may do a better job here, I'd expect.)

    Once I needed a function to produce Gaussian noise - and nothing else!
    (Back then I used, I think, the Fortran IMSL library.) - In a modern modules-supporting environment I'd have liked to have something like

    use imsl.math.rand.gauss

    I don't want the whole library, nor the whole math package, nor all
    the random functions. I want them neither pollute my namespace, nor
    do I want that libraries, library components, or functions are even
    considered for inclusion, neither on the program text level, nor at
    the binary module level, if they are not needed.

    In case of name clashes that happen despite a pinpointed inclusion
    there's still an optional qualification syntax necessary. - In case
    of the above example the "structuring path" could be used for that,
    say, for example, something like rand.gauss and matrix.gauss .


    You seem to be favouring just type 2 - or even a "from * import *"
    solution.˙ That might be convenient for a personal language where you
    are the only one ever writing the code - you know there are no
    collisions, because you wrote everything.˙ For anyone else, working
    outside a bubble, it is unscalable.

    What I find annoying with his posts is that from within his bubble he's
    not even trying to look outside his horizon, even with obvious things.
    His inept exaggerations, the sloppiness, and misrepresentations add to
    the annoyance. - I'm tired.

    Thanks for taking the task to explain that to him.

    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 Thu Sep 10 23:48:04 2026
    On 10/09/2026 23:06, Janis Papanagnou wrote:
    On 2026-09-10 09:48, David Brown wrote:
    On 10/09/2026 00:30, bart wrote:
    On 09/09/2026 22:26, Janis Papanagnou wrote:
    [...]
    [...]
    [...]

    Each type of import has its own advantages and disadvantages.

    Type 1 would need micro-management if you want a lot of symbols from a
    module.˙ But if you only need a small number, it can keep things neat
    - you only see what you actually want to use.˙ And if the imported
    module only really exports a single name (like "my_class.py" exporting
    "My_Class"), it's a neat solution that avoids later code clutter from
    having to specify the module name.

    Type 2 lets you immediately use all the identifiers from the module,
    but causes a lot of problems if things change in the future.˙ Maybe
    your own code has a function "fluff", and a later version of
    "foobar.py" also adds a function "fluff".˙ That is not going to be good.

    Type 3 lets you conveniently import all the exported symbols from the
    module, but you need to specify the namespace when using them.


    As I see it, Janis favours that kind of flexibility for modules
    (though of course the details may differ for different languages).

    Since you mentioned me - and since I don't intend after my thorough explanation to spend yet more time with bart's posts about it - let
    me confirm your interpretation, and give an example from practice.

    Note also that none of the languages I'm currently using is supporting
    that principle - there's no "best" language in that respect, although
    some are closer to an ideal modularization than others. (Some recent languages [that I don't know] may do a better job here, I'd expect.)

    Once I needed a function to produce Gaussian noise - and nothing else!
    (Back then I used, I think, the Fortran IMSL library.) - In a modern modules-supporting environment I'd have liked to have something like

    ˙ use imsl.math.rand.gauss

    I don't want the whole library, nor the whole math package, nor all
    the random functions. I want them neither pollute my namespace, nor
    do I want that libraries, library components, or functions are even considered for inclusion, neither on the program text level, nor at
    the binary module level, if they are not needed.

    In case of name clashes that happen despite a pinpointed inclusion
    there's still an optional qualification syntax necessary. - In case
    of the above example the "structuring path" could be used for that,
    say, for example, something like˙ rand.gauss˙ and˙ matrix.gauss .


    You seem to be favouring just type 2 - or even a "from * import *"
    solution.˙ That might be convenient for a personal language where you
    are the only one ever writing the code - you know there are no
    collisions, because you wrote everything.˙ For anyone else, working
    outside a bubble, it is unscalable.

    What I find annoying with his posts is that from within his bubble he's
    not even trying to look outside his horizon,

    You don't try to look much outside yours either.

    But also, the difference between you and me is that I devise my own
    solutions, and do not have to settle for someone else's decisions.

    In any case, my module scheme is intended to work between the
    constituent modules of programs designed to work with whole-program compilation, more than for external libraries written by someone else.

    Generally these have to be more 'chummy' and are non-hierarchical, but
    there are hierarchical options within the program's modules too for
    better segregation and structure.

    His inept exaggerations, the sloppiness,


    When you have to implement this stuff then you can't be sloppy. Perhaps
    you're just jealous that my scheme isn't available in your favourite
    language.



    --- 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 Fri Sep 11 00:48:52 2026
    On 2026-09-10 10:11, David Brown wrote:
    On 09/09/2026 23:07, Janis Papanagnou wrote:
    [...]

    But there need not be a problem using '=' for assignments and also
    for comparisons if the respective languages could tell them apart by
    context and with appropriate semantic rules.

    Agreed.˙ In my "dream language", assignment would be a statement, not an expression, which lets you use the same symbol.

    I'm not sure it's a good idea to have the same symbol here. I'd
    certainly prefer a separate symbol anyway. (Notwithstanding that
    a context dependent differentiation is or might be possible.)

    I suppose "C" has adopted the assignment being an expression from
    Algol 68; but in the latter case we *do* have separate symbols.
    I suspect that "C" might have just used a '=' instead of the back
    then already not uncommon ':=' just to save some tying?
    The "problem" is obviously not the assignment-expression per se;
    but the comprised design choices of the C-language as a whole.

    Indeed, assignment
    would be very rare - normally variables would be initialised once, and
    never changed.

    Incidentally that's exactly what I observed in recent times when
    I recovered my Algol 68 programming; the language defines such a
    handling by "identity declarations".
    INT answer = 42 defines an item of reference level 0 (constant)
    INT state := 0 defines/initializes a variable (reference level 1)
    and I noticed in my programs a prevalence of identity declarations
    and mostly only few variables.

    Given that observation it may be unfortunate that we need explicit
    'const' to specify such identities in "C", a language that strived
    for terseness (as it seems).

    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 Thu Sep 10 15:52:52 2026
    bart <bc@freeuk.com> writes:
    [...]
    But also, the difference between you and me is that I devise my own solutions, and do not have to settle for someone else's decisions.

    And you insist on discussing your solutions in comp.lang.c.

    I see you've posted to comp.lang.misc. I encourage you to do so more
    often.

    [...]

    When you have to implement this stuff then you can't be
    sloppy. Perhaps you're just jealous that my scheme isn't available in
    your favourite language.

    When you're the only user, you can get away with being sloppy and
    covering only the use cases that apply to 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 fir@3:633/10 to All on Fri Sep 11 01:04:15 2026
    fir pisze:
    bart pisze:
    On 10/09/2026 15:59, fir wrote:
    fir pisze:
    Try it with a real example, such as:

    ˙˙˙˙˙ succeeded =˙ tdefl_init pComp˙ pPut_buf_func˙ pPut_buf_user
    flags == TDEFL_STATUS_OKAY ;

    ˙˙˙˙˙ succeeded = succeeded &&˙ tdefl_compress_buffer pComp˙ pBuf
    buf_len˙ TDEFL_FINISH == TDEFL_STATUS_DONE


    im not sure what you mean hera bove but with this e conventions im
    talkin abouts its

    succeeded =˙ tdefl_init( pComp,˙ pPut_buf_func,˙ pPut_buf_user,
    flags== TDEFL_STATUS_OKAY) ;

    Not bad, but this is the original:

    ˙˙ succeeded = (tdefl_init(pComp, pPut_buf_func, pPut_buf_user, flags)
    == TDEFL_STATUS_OKAY);


    thet would be

    succeeded = (tdefl_init pComp˙ pPut_buf_func˙ pPut_buf_user˙ flags ) == TDEFL_STATUS_OKAY




    and

    succeeded = succeeded &&˙ tdefl_compress_buffer( pComp , pBuf,
    buf_len, TDEFL_FINISH == TDEFL_STATUS_DONE);
    And here's the original for this:

    ˙˙˙˙ succeeded = succeeded && (tdefl_compress_buffer(pComp, pBuf,
    buf_len, TDEFL_FINISH) == TDEFL_STATUS_DONE);


    I think the parentheses and commas do a good job in removing ambiguity.

    Although the originals probably had one pair of superfluous
    parentheses each, as '=='s precedence is already higher than both =
    and &&.

    But, what are you planning with general expressions: will you still
    have operator precedences?


    if the comma and parenthesis are not needed why use them

    esp as a most amount of code is like

    ˙void RunFrame advance
    ˙{
    ˙˙˙˙˙ Initialise,
    ˙˙˙˙˙ ClearFrameData 0x444444
    ˙˙˙˙˙ DrawLine3d 100.0˙˙ 100.0˙˙ 0.0˙˙˙˙ 100.0 -100.0 0.0˙˙˙ 0xffffff
    ˙˙˙˙˙ DrawLine3d 100.0˙ -100.0˙˙ 0.0˙˙˙ -100.0 -100.0 0.0˙˙˙ 0xffffff
    ˙˙˙˙˙ DrawLine3d -100.0 -100.0˙˙ 0.0˙˙˙ -100.0˙ 100.0 0.0˙˙˙ 0xffffff
    ˙˙˙˙˙ DrawLine3d -100.0˙ 100.0˙˙ 0.0˙˙˙˙ 100.0˙ 100.0 0.0˙˙˙ 0xffffff
    ˙˙˙˙˙ DrawDot3d 0.0 0.0 100.0˙˙ 20.0˙ 0x557788
    ˙˙˙˙˙ DrawDot3d 0.0 0.0 150.0˙˙ 30.0˙ 0x557722
    ˙˙˙˙˙ DrawDot3d 0.0 0.0 -100.0˙ 10.0˙ 0xaa7788
    ˙˙˙˙˙ InitSomeJointsFigures
    ˙˙˙˙˙ DrawCloud1, DrawCloud2,
    ˙˙˙˙ DrawCloud11, DrawCloud12, UpdateDotsBag, DrawDotsBag

    ˙FillRectangle2 10 10 20 20 color
    ˙˙ DrawSomeText2F 0xcccccc 0x666666 20 10 " %x \x00"˙˙ 0xffffff
    ˙˙ DrawSomeText2F 0xcccccc 0x666666 10 20 "hello, this is example
    program compiled by fir's furia compiler \x00"

    ˙˙˙ DeawLines
    ˙˙˙ DrawTextByBalls "hello\x00" 0 0 0x999999
    ˙˙˙ DrawCubesCubeGeo

    ˙˙ BezierPatchTest

    ˙˙ space_pressed? FireDotFromCameraCurrentColor 0.0 0.0 100000 20
    ˙˙ a_pressed?!˙ FireDotFromCameraCurrentColor 1.0 0.0 10000 20
    ˙˙ f5_toggler? DrawManual

    ˙˙ DrawFloor 20000 30 0x555555
    ˙˙ DrawRawModel

    ˙}

    i mean lot are "normal" simple calls and there is a lot of (,,,,);
    to skip
    as to operator precedence ofc its needed and as i said what i show
    here is the part that is "resolved" but there are more complex
    cases where it is not resolved yet

    (for example for this many return values , operator form of functions
    (as a would like to have "x foo y" where foo is a function and x y are arguments, and those float char types, some constructions like loops
    and so on


    i consider yet such syntax


    ?mandelbrot_calculate ?image_beg_x ?image_beg_y ?image_end_x
    ?image_end_y ?ox ?oy ?lx ?max_iter
    {
    ly? lx*frame_size_y/frame_size_x
    dx? lx/frame_size_x
    dy? lx/frame_size_x
    ax? ox-lx*.5+dx*.5
    ay? oy-ly*.5+dy*.5

    j? image_beg_y..image_end_y { c_im? ay+j*dy
    i? image_beg_x..image_end_x { c_re? ax+i*dx
    n? mandelbrot_n c_re c_im max_iter, suma? suma+n,
    OffscreenBufferSetValue i j n }}
    }


    ax? mean "double ax ="
    ?image_beg_y means "?image_beg_y"
    n? means "int n ="

    and so on

    so this will cover doubles and ints but no solutions for chars floats
    schorts, defined types etc - so it may be a problem (alse those
    typenames in heaer consumes types/chars


    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From bart@3:633/10 to All on Fri Sep 11 00:37:29 2026
    On 10/09/2026 08:48, David Brown wrote:
    On 10/09/2026 00:30, bart wrote:
    On 09/09/2026 22:26, Janis Papanagnou wrote:
    On 2026-09-09 20:12, bart wrote:
    On 09/09/2026 02:59, Waldek Hebisch wrote:
    [...]

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

    I fear you're just exposing your very limited perception and experience
    here. (And en passant probably also the mindset of a technocratic paper
    pusher than a software designer.)

    Myself I'm favoring _to be able_ to import only what I need and not the
    whole bunch of existing things of a module (with all potential implicit
    and explicit consequences).
    Why? What is the advantage of so much micromanagement?

    Consider modules in Python, since that is a language with "real" modules
    and with which many people are familiar.

    # foobar.py
    def foo() : return "foo"
    def bar() : return "bar"


    Another file user.py wants to use "foo" from "foobar.py".˙ They can do
    so in three main ways :

    1. Specific inclusion

    from foobar import foo
    x = foo()


    2. Global namespace inclusion

    from foobar import *
    x = foo()


    3. Module namespace inclusion

    import foobar
    x = foobar.foo()


    Each type of import has its own advantages and disadvantages.

    Type 1 would need micro-management if you want a lot of symbols from a module.˙ But if you only need a small number, it can keep things neat -
    you only see what you actually want to use.

    Python doesn't have export attributes. That means that every top- or module-level identifier can be imported into another module.

    In mine, entities have to be explicitly exported to be visible outside.
    That means importing everything that a module exports is fine; that's
    the idea!


    And if the imported module
    only really exports a single name (like "my_class.py" exporting
    "My_Class"), it's a neat solution that avoids later code clutter from
    having to specify the module name.

    I allow that anyway. Unless two modules export the same name then the
    compiler complains. However a local name can silently shadow an imported
    name, but that's how scopes work in general.


    Type 2 lets you immediately use all the identifiers from the module, but causes a lot of problems if things change in the future.˙ Maybe your own code has a function "fluff", and a later version of "foobar.py" also
    adds a function "fluff".˙ That is not going to be good.

    Type 3 lets you conveniently import all the exported symbols from the module, but you need to specify the namespace when using them.


    As I see it, Janis favours that kind of flexibility for modules (though
    of course the details may differ for different languages).


    You seem to be favouring just type 2 - or even a "from * import *"
    solution.

    Mine actually can be a little more sophisticated. Say for example you
    have a mini-library of three modules, and the whole exports several
    functions from across those modules.

    In Python you'd have to import all three modules: you'd need to now the internal structure, which in future can change.

    With mine, you just import the lead module of the three. If
    qualification is needed, then you use the name of the lead module; the internal structure is opaque.

    It is also possible to encapsulate a bunch of functions and stuff which
    is only available via a namespace.

    That might be convenient for a personal language where you
    are the only one ever writing the code - you know there are no
    collisions, because you wrote everything.˙ For anyone else, working
    outside a bubble, it is unscalable.


    As I explained in a post a little while ago, my module scheme is mainly intended to manage the modules of a single program intended for
    whole-program compilation. That includes self-contain mini-libraries
    which are statically compiled into the app.

    For external libraries, there is a separate approach called the 'FFI'.

    There, typically, I would need to create bindings. For my SDL3 example,
    that would define 1200 functions, plus 3000 more named constants,
    macros, enumerations, structs and types.

    This is not part of the module scheme, other than the bindings for
    imported FFI functions being with a container module that will re-export
    them for use with the rest of the application. That container module
    will wrap them in an optional namespace.

    Here it would obviously be ludicrous to micro-manage large, unwieldy
    subsets of those 4000 names. A program would just do:

    module sdl # sdl.m contains the 4000 lines which is condensed
    # form of the 86 SDL3 headers

    Then all 4000 names will be available. The same as in C, except that I
    can shadow them if needed.

    I can call SDL3 functions like this:

    sql_quit()

    This is SDL_Quit in C, but my language allows any case. Or I can apply
    the qualifier:

    sdl.sql_quit()

    But this is obviously a bit silly; SDL names already have a special prefix.

    That 'module sdl' line BTW exists in one place in the program. The 4K
    sdl.m module is compiled once no matter how many modules in all.


    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From bart@3:633/10 to All on Fri Sep 11 00:48:12 2026
    On 10/09/2026 23:52, Keith Thompson wrote:
    bart <bc@freeuk.com> writes:
    [...]
    But also, the difference between you and me is that I devise my own
    solutions, and do not have to settle for someone else's decisions.

    And you insist on discussing your solutions in comp.lang.c.

    I see you've posted to comp.lang.misc. I encourage you to do so more
    often.

    Look, this group is more or less dead (you can thank fir for breathing
    some life into it recently!), and comp.lang.misc pretty much is. Besides nobody bothers with topicality any more.

    At least I still discuss related technical topics.

    [...]

    When you have to implement this stuff then you can't be
    sloppy. Perhaps you're just jealous that my scheme isn't available in
    your favourite language.

    When you're the only user, you can get away with being sloppy and
    covering only the use cases that apply to you.



    The scheme I use would suffice for ALL projects I've worked on; ALL
    programs I've written in C (not many); and many open source C projects
    that I've come across.

    (I can't say 'most', as they are often too complex and chaotic to see if
    my approach would apply.)

    And I repeat, when you have to implement it, it has to work. It's no
    good if it's buggy!

    --- 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 Thu Sep 10 17:11:15 2026
    bart <bc@freeuk.com> writes:
    On 10/09/2026 23:52, Keith Thompson wrote:
    [...]
    I see you've posted to comp.lang.misc. I encourage you to do so more
    often.

    [...]
    Besides nobody bothers with topicality any more.

    Manifestly untrue.

    [...]
    When you have to implement this stuff then you can't be
    sloppy. Perhaps you're just jealous that my scheme isn't available in
    your favourite language.

    When you're the only user, you can get away with being sloppy and
    covering only the use cases that apply to you.
    [...]

    To be clear, that wasn't necessarily meant as a criticism. When I
    wrote code for my own use, I feel free to ignore cases that I
    personally don't find useful -- cases that I would want to cover
    if I were to share the code publicly.

    --
    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 David Brown@3:633/10 to All on Fri Sep 11 09:16:44 2026
    On 10/09/2026 23:08, Chris M. Thomasson wrote:
    On 9/9/2026 5:43 AM, David Brown wrote:
    [...]
    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.

    ________
    #ifndef __NUMBER_GENERATOR_H__
    #define __NUMBER_GENERATOR_H__ 1
    ________


    Is that __* non conformant? Does it breach the impl name prefix space?

    Yes. As Keith pointed out, using "H_NUMBER_GENERATOR_" or similar is
    better. Various conventions are used, and usually the risk of
    collisions with implementations is entirely negligible. But there is no
    cost in avoiding reserved prefixes, so you might as well do so.


    --- 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 Fri Sep 11 09:21:59 2026
    On 10/09/2026 19:17, fir wrote:
    David Brown pisze:
    On 10/09/2026 18:21, fir wrote:
    David Brown pisze:


    Either this is just a waste of time (and the fact that most of your
    posts are replies to your own posts suggest that this is the case), or
    you are really interested in making a new language - and
    comp.lang.misc would be a better place to discuss it.



    how it suggest that? note thise are 'replies' maybe in some technical
    sense of a usenet reader..but on thought /write level they are just continuation of thoughts/topic..its rather quite artificall to write ll
    you got to say in one post and assume you have nothing to add ..i often
    have things to add


    Public forums - like a Usenet group - are not like having a whiteboard
    on your wall. If you ask questions that are topical to the group, or
    make comments or replies that are topical to the group, that's great.
    When you ramble with wild ideas, post after post, that's just wasting everyone's time. People don't give any feedback, and mostly skip them.

    So please, write your ramblings on a bit of paper or a whiteboard. When
    you have something worth sharing with other people, and you want
    feedback or help, post them to an appropriate group. If it is actually
    about C, that's comp.lang.c. If it is about a weird new language with
    lots of Unicode signs and a very different syntax, comp.lang.misc is a
    better choice.

    This is surely not difficult to understand.


    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From fir@3:633/10 to All on Fri Sep 11 12:46:11 2026
    David Brown pisze:
    On 10/09/2026 19:17, fir wrote:
    David Brown pisze:
    On 10/09/2026 18:21, fir wrote:
    David Brown pisze:


    Either this is just a waste of time (and the fact that most of your
    posts are replies to your own posts suggest that this is the case),
    or you are really interested in making a new language - and
    comp.lang.misc would be a better place to discuss it.



    how it suggest that? note thise are 'replies' maybe in some technical
    sense of a usenet reader..but on thought /write level they are just
    continuation of thoughts/topic..its rather quite artificall to write
    ll you got to say in one post and assume you have nothing to add ..i
    often have things to add


    Public forums - like a Usenet group - are not like having a whiteboard
    on your wall.˙ If you ask questions that are topical to the group, or
    make comments or replies that are topical to the group, that's great.
    When you ramble with wild ideas, post after post, that's just wasting everyone's time.˙ People don't give any feedback, and mostly skip them.

    So please, write your ramblings on a bit of paper or a whiteboard.˙ When
    you have something worth sharing with other people, and you want
    feedback or help, post them to an appropriate group.˙ If it is actually about C, that's comp.lang.c.˙ If it is about a weird new language with
    lots of Unicode signs and a very different syntax, comp.lang.misc is a better choice.

    This is surely not difficult to understand.


    what you say is shallow looking on C so i cant agree... you try to
    impose you shallow view (just some way like keith thompson want to
    impose his rigid rukles here that this group is only for standard freaks)

    i may partially agree that some investigation in possible c syntax/skin
    are somewhat intermediate - but those are intermediate results kinda
    needed to obtain final conclusions

    i dont much can do something with fact that some post dont interest you
    - belive many posts who many wrote here not interest me also (like
    things keith writes, or trigraph topic and many more)
    (regular c stuff is also not so much interesting, its ok, but some
    deeper c ideas much more interesting)



    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From fir@3:633/10 to All on Fri Sep 11 14:13:10 2026
    fir pisze:
    David Brown pisze:
    On 10/09/2026 19:17, fir wrote:
    David Brown pisze:
    On 10/09/2026 18:21, fir wrote:
    David Brown pisze:


    Either this is just a waste of time (and the fact that most of your
    posts are replies to your own posts suggest that this is the case),
    or you are really interested in making a new language - and
    comp.lang.misc would be a better place to discuss it.



    how it suggest that? note thise are 'replies' maybe in some technical
    sense of a usenet reader..but on thought /write level they are just
    continuation of thoughts/topic..its rather quite artificall to write
    ll you got to say in one post and assume you have nothing to add ..i
    often have things to add


    Public forums - like a Usenet group - are not like having a whiteboard
    on your wall.˙ If you ask questions that are topical to the group, or
    make comments or replies that are topical to the group, that's great.
    When you ramble with wild ideas, post after post, that's just wasting
    everyone's time.˙ People don't give any feedback, and mostly skip them.

    So please, write your ramblings on a bit of paper or a whiteboard.
    When you have something worth sharing with other people, and you want
    feedback or help, post them to an appropriate group.˙ If it is
    actually about C, that's comp.lang.c.˙ If it is about a weird new
    language with lots of Unicode signs and a very different syntax,
    comp.lang.misc is a better choice.

    This is surely not difficult to understand.


    what you say is shallow looking on C so i cant agree... you try to
    impose you shallow view (just some way like keith thompson want to
    impose˙ his rigid rukles here that this group is only for standard freaks)

    i may partially agree that some investigation in possible c syntax/skin
    are somewhat intermediate - but those are intermediate results kinda
    needed to obtain final conclusions

    i dont much can do something with fact that some post dont interest you
    - belive many posts who many wrote here not interest me also (like
    things keith writes, or trigraph topic and many more)
    (regular c stuff is also not so much interesting, its ok, but some
    deeper c ideas much more interesting)



    speaking about this whiteboard or blackboard : also not this group has
    some historical value and people may be interested how this great new
    language by fir was born (great new B or great new C or great new D
    or even more like great new E or ? or í still problems with tha name

    if i took a way to use unicode maybe i should take unicode sign?
    it will make all this printers to print unicode in papers so that would
    be kinda new impact )

    --- 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 Fri Sep 11 13:41:58 2026
    On 11/09/2026 13:13, fir wrote:
    speaking about this whiteboard or blackboard : also not this group has
    some historical value and people may be interested how this great new language by fir was born (great new B or great new C or great new D
    or even more like great new E˙ or ? or í still problems with tha name

    If you're looking for a name for your new language ...
    ... might I suggest ?



    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From fir@3:633/10 to All on Fri Sep 11 14:55:29 2026
    Richard Harnden pisze:
    On 11/09/2026 13:13, fir wrote:
    speaking about this whiteboard or blackboard : also not this group has
    some historical value and people may be interested how this great new
    language by fir was born (great new B or great new C or great new D
    or even more like great new E˙ or ? or í still problems with tha name

    If you're looking for a name for your new language ...
    ... might I suggest ?


    assuming that im right and youre part of history - youre get known for
    this - and its not so much glorious legacy

    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From fir@3:633/10 to All on Fri Sep 11 15:01:46 2026
    fir pisze:
    Richard Harnden pisze:
    On 11/09/2026 13:13, fir wrote:
    speaking about this whiteboard or blackboard : also not this group
    has some historical value and people may be interested how this great
    new language by fir was born (great new B or great new C or great new D
    or even more like great new E˙ or ? or í still problems with tha name

    If you're looking for a name for your new language ...
    ... might I suggest ?


    assuming that im right and youre part of history - youre get known for
    this - and its not so much glorious legacy

    im a bit joking here but note 'joking' is giving to know thet what some
    say is in some way not to 'stright' understanding but not exactly
    precisiszing whet is not 'strict' and what not

    i hjust now wana go frome one banal to another (and one strict view on
    thing turned into quite another different strict view may become turnin
    banal into banal and the progres is for me from somewhat banal or not
    balal into less banal


    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From fir@3:633/10 to All on Fri Sep 11 15:04:15 2026
    fir pisze:
    Richard Harnden pisze:
    On 11/09/2026 13:13, fir wrote:
    speaking about this whiteboard or blackboard : also not this group
    has some historical value and people may be interested how this great
    new language by fir was born (great new B or great new C or great new D
    or even more like great new E˙ or ? or í still problems with tha name

    If you're looking for a name for your new language ...
    ... might I suggest ?


    assuming that im right and youre part of history - youre get known for
    this - and its not so much glorious legacy

    i hope though history will not remember it too much becouse it would
    spoil its mood to remember such ultra banal and low outcomes
    (even not so much representative fortunatelly)


    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From fir@3:633/10 to All on Fri Sep 11 15:08:27 2026
    fir pisze:
    fir pisze:
    David Brown pisze:
    On 10/09/2026 19:17, fir wrote:
    David Brown pisze:
    On 10/09/2026 18:21, fir wrote:
    David Brown pisze:


    Either this is just a waste of time (and the fact that most of your >>>>> posts are replies to your own posts suggest that this is the case), >>>>> or you are really interested in making a new language - and
    comp.lang.misc would be a better place to discuss it.



    how it suggest that? note thise are 'replies' maybe in some
    technical sense of a usenet reader..but on thought /write level they
    are just continuation of thoughts/topic..its rather quite artificall
    to write ll you got to say in one post and assume you have nothing
    to add ..i often have things to add


    Public forums - like a Usenet group - are not like having a
    whiteboard on your wall.˙ If you ask questions that are topical to
    the group, or make comments or replies that are topical to the group,
    that's great. When you ramble with wild ideas, post after post,
    that's just wasting everyone's time.˙ People don't give any feedback,
    and mostly skip them.

    So please, write your ramblings on a bit of paper or a whiteboard.
    When you have something worth sharing with other people, and you want
    feedback or help, post them to an appropriate group.˙ If it is
    actually about C, that's comp.lang.c.˙ If it is about a weird new
    language with lots of Unicode signs and a very different syntax,
    comp.lang.misc is a better choice.

    This is surely not difficult to understand.


    what you say is shallow looking on C so i cant agree... you try to
    impose you shallow view (just some way like keith thompson want to
    impose˙ his rigid rukles here that this group is only for standard
    freaks)

    i may partially agree that some investigation in possible c syntax/skin
    are somewhat intermediate - but those are intermediate results kinda
    needed to obtain final conclusions

    i dont much can do something with fact that some post dont interest
    you - belive many posts who many wrote here not interest me also (like
    things keith writes, or trigraph topic and many more)
    (regular c stuff is also not so much interesting, its ok, but some
    deeper c ideas much more interesting)



    speaking about this whiteboard or blackboard : also not this group has
    some historical value and people may be interested how this great new language by fir was born (great new B or great new C or great new D
    or even more like great new E˙ or ? or í still problems with tha name


    there is also an option of ? to consider

    if i took a way to use unicode maybe i should take unicode sign?
    it will make all this printers to print unicode in papers so that would
    be kinda new impact )


    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From fir@3:633/10 to All on Fri Sep 11 15:13:43 2026
    fir pisze:
    fir pisze:
    fir pisze:
    David Brown pisze:
    On 10/09/2026 19:17, fir wrote:
    David Brown pisze:
    On 10/09/2026 18:21, fir wrote:
    David Brown pisze:


    Either this is just a waste of time (and the fact that most of
    your posts are replies to your own posts suggest that this is the >>>>>> case), or you are really interested in making a new language - and >>>>>> comp.lang.misc would be a better place to discuss it.



    how it suggest that? note thise are 'replies' maybe in some
    technical sense of a usenet reader..but on thought /write level
    they are just continuation of thoughts/topic..its rather quite
    artificall to write ll you got to say in one post and assume you
    have nothing to add ..i often have things to add


    Public forums - like a Usenet group - are not like having a
    whiteboard on your wall.˙ If you ask questions that are topical to
    the group, or make comments or replies that are topical to the
    group, that's great. When you ramble with wild ideas, post after
    post, that's just wasting everyone's time.˙ People don't give any
    feedback, and mostly skip them.

    So please, write your ramblings on a bit of paper or a whiteboard.
    When you have something worth sharing with other people, and you
    want feedback or help, post them to an appropriate group.˙ If it is
    actually about C, that's comp.lang.c.˙ If it is about a weird new
    language with lots of Unicode signs and a very different syntax,
    comp.lang.misc is a better choice.

    This is surely not difficult to understand.


    what you say is shallow looking on C so i cant agree... you try to
    impose you shallow view (just some way like keith thompson want to
    impose˙ his rigid rukles here that this group is only for standard
    freaks)

    i may partially agree that some investigation in possible c syntax/skin
    are somewhat intermediate - but those are intermediate results kinda
    needed to obtain final conclusions

    i dont much can do something with fact that some post dont interest
    you - belive many posts who many wrote here not interest me also
    (like things keith writes, or trigraph topic and many more)
    (regular c stuff is also not so much interesting, its ok, but some
    deeper c ideas much more interesting)



    speaking about this whiteboard or blackboard : also not this group has
    some historical value and people may be interested how this great new
    language by fir was born (great new B or great new C or great new D
    or even more like great new E˙ or ? or í still problems with tha name


    there is also an option of ? to consider


    this one may be clever as you may treat C as a mooon shape it suggest
    that C might enetered a new mooon (black moon) and after this is ?
    phase - C rising again..assuming C and ? are both parts of O

    it is some kind of pleasing, but enough to take it?



    if i took a way to use unicode maybe i should take unicode sign?
    it will make all this printers to print unicode in papers so that
    would be kinda new impact )



    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From fir@3:633/10 to All on Fri Sep 11 15:17:05 2026
    fir pisze:
    fir pisze:
    fir pisze:
    fir pisze:
    David Brown pisze:
    On 10/09/2026 19:17, fir wrote:
    David Brown pisze:
    On 10/09/2026 18:21, fir wrote:
    David Brown pisze:


    Either this is just a waste of time (and the fact that most of
    your posts are replies to your own posts suggest that this is the >>>>>>> case), or you are really interested in making a new language -
    and comp.lang.misc would be a better place to discuss it.



    how it suggest that? note thise are 'replies' maybe in some
    technical sense of a usenet reader..but on thought /write level
    they are just continuation of thoughts/topic..its rather quite
    artificall to write ll you got to say in one post and assume you
    have nothing to add ..i often have things to add


    Public forums - like a Usenet group - are not like having a
    whiteboard on your wall.˙ If you ask questions that are topical to
    the group, or make comments or replies that are topical to the
    group, that's great. When you ramble with wild ideas, post after
    post, that's just wasting everyone's time.˙ People don't give any
    feedback, and mostly skip them.

    So please, write your ramblings on a bit of paper or a whiteboard.
    When you have something worth sharing with other people, and you
    want feedback or help, post them to an appropriate group.˙ If it is >>>>> actually about C, that's comp.lang.c.˙ If it is about a weird new
    language with lots of Unicode signs and a very different syntax,
    comp.lang.misc is a better choice.

    This is surely not difficult to understand.


    what you say is shallow looking on C so i cant agree... you try to
    impose you shallow view (just some way like keith thompson want to
    impose˙ his rigid rukles here that this group is only for standard
    freaks)

    i may partially agree that some investigation in possible c syntax/skin >>>> are somewhat intermediate - but those are intermediate results kinda
    needed to obtain final conclusions

    i dont much can do something with fact that some post dont interest
    you - belive many posts who many wrote here not interest me also
    (like things keith writes, or trigraph topic and many more)
    (regular c stuff is also not so much interesting, its ok, but some
    deeper c ideas much more interesting)



    speaking about this whiteboard or blackboard : also not this group
    has some historical value and people may be interested how this great
    new language by fir was born (great new B or great new C or great new D
    or even more like great new E˙ or ? or í still problems with tha name


    there is also an option of ? to consider


    this one may be clever as you may treat C as a mooon shape it suggest
    that C might enetered a new mooon (black moon) and after this is˙ ?
    phase - C rising again..assuming C and˙ ? are both parts of O

    it is some kind of pleasing, but enough to take it?




    okay for now its somewhat pleasing , so i take it for now,
    (takin in considaretion my words on barbarians, ? fits in that story )
    but no guarantee i dont chamge it

    (bit for now its reserved)



    if i took a way to use unicode maybe i should take unicode sign?
    it will make all this printers to print unicode in papers so that
    would be kinda new impact )




    --- 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 Sat Sep 12 08:01:33 2026
    bart <bc@freeuk.com> writes:

    When you have to implement this stuff then you can't be sloppy.

    You demonstrated you can be extremely sloppy in your thinking and
    in your argumentation! That doesn't mean that you wouldn't be able
    to "write programs" ("this stuff"), for sure. - Another example of
    sloppy thinking and argumentation.

    Perhaps you're just jealous

    Your mindset is so primitive, naive, and erroneous; unprecedentedly
    given your stubbornness. Your persistent habit of making guesses,
    completely missing the point, topics, and characters, had regularly
    been shown to be widely erroneous. - I see you can't just stop your
    ineffective tries. It won't lead you anywhere.

    that my scheme isn't available in your favourite language.

    I have no "favourite language". (In a couple languages there's some
    concepts that I'd like to be more widely spread. - Not sure you're
    capable of understanding that and notice the blatant difference!)

    And you should meanwhile know that meaningless home-brewed languages
    are neither of general interest nor of mine; but you seem to have a
    persisting mental hindrance to understand what is easy understandable
    by others. - Just to be clear; I don't know that "my scheme" you're
    talking about is because I'm not interested in your posts about your
    personal tools.

    (I also suggest to become a bit more honest about your "achievement"
    with creating your tool unless it gets some minimum general relevance
    beyond your micro-ecosystem. - Why don't you advertise and offer your
    tools at any more appropriate place if you think they're so important, innovative, or generally useful?!)

    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 Sat Sep 12 08:20:46 2026
    Janis Papanagnou pisze:
    bart <bc@freeuk.com> writes:

    When you have to implement this stuff then you can't be sloppy.

    You demonstrated you can be extremely sloppy in your thinking and
    in your argumentation! That doesn't mean that you wouldn't be able
    to "write programs" ("this stuff"), for sure. - Another example of
    sloppy thinking and argumentation.

    Perhaps you're just jealous

    Your mindset is so primitive, naive, and erroneous; unprecedentedly
    given your stubbornness. Your persistent habit of making guesses,
    completely missing the point, topics, and characters, had regularly
    been shown to be widely erroneous. - I see you can't just stop your ineffective tries. It won't lead you anywhere.

    that my scheme isn't available in your favourite language.

    I have no "favourite language". (In a couple languages there's some
    concepts that I'd like to be more widely spread. - Not sure you're
    capable of understanding that and notice the blatant difference!)

    And you should meanwhile know that meaningless home-brewed languages
    are neither of general interest nor of mine; but you seem to have a persisting mental hindrance to understand what is easy understandable
    by others. - Just to be clear; I don't know that "my scheme" you're
    talking about is because I'm not interested in your posts about your
    personal tools.

    (I also suggest to become a bit more honest about your "achievement"
    with creating your tool unless it gets some minimum general relevance
    beyond your micro-ecosystem. - Why don't you advertise and offer your
    tools at any more appropriate place if you think they're so important, innovative, or generally useful?!)

    Janis

    lol, i told keith's team are funny asses..it needs some funcy answer:

    you say 'usefull', i tell "your mum is doin new school"

    https://www.youtube.com/watch?v=cumbkA5dGDI




    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From fir@3:633/10 to All on Sat Sep 12 09:09:06 2026
    fir pisze:
    Janis Papanagnou pisze:
    bart <bc@freeuk.com> writes:

    When you have to implement this stuff then you can't be sloppy.

    You demonstrated you can be extremely sloppy in your thinking and
    in your argumentation! That doesn't mean that you wouldn't be able
    to "write programs" ("this stuff"), for sure. - Another example of
    sloppy thinking and argumentation.

    Perhaps you're just jealous

    Your mindset is so primitive, naive, and erroneous; unprecedentedly
    given your stubbornness. Your persistent habit of making guesses,
    completely missing the point, topics, and characters, had regularly
    been shown to be widely erroneous. - I see you can't just stop your
    ineffective tries. It won't lead you anywhere.

    that my scheme isn't available in your favourite language.

    I have no "favourite language". (In a couple languages there's some
    concepts that I'd like to be more widely spread. - Not sure you're
    capable of understanding that and notice the blatant difference!)

    And you should meanwhile know that meaningless home-brewed languages
    are neither of general interest nor of mine; but you seem to have a
    persisting mental hindrance to understand what is easy understandable
    by others. - Just to be clear; I don't know that "my scheme" you're
    talking about is because I'm not interested in your posts about your
    personal tools.

    (I also suggest to become a bit more honest about your "achievement"
    with creating your tool unless it gets some minimum general relevance
    beyond your micro-ecosystem. - Why don't you advertise and offer your
    tools at any more appropriate place if you think they're so important,
    innovative, or generally useful?!)

    Janis

    lol, i told keith's team are funny asses..it needs some funcy answer:

    you say 'usefull', i tell "your mum is doin new school"

    https://www.youtube.com/watch?v=cumbkA5dGDI


    sorry becouse my bad english i am rather unable to catch some more
    subtle things in this anglish so maybe it should be

    you say 'usefull', i tell your mama is doin new school

    maybe this would be more appropriate

    (by crom.. i feel body pain again)
    (fir)

    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From fir@3:633/10 to All on Sat Sep 12 12:35:09 2026
    fir pisze:
    fir pisze:
    Janis Papanagnou pisze:
    bart <bc@freeuk.com> writes:

    When you have to implement this stuff then you can't be sloppy.

    You demonstrated you can be extremely sloppy in your thinking and
    in your argumentation! That doesn't mean that you wouldn't be able
    to "write programs" ("this stuff"), for sure. - Another example of
    sloppy thinking and argumentation.

    Perhaps you're just jealous

    Your mindset is so primitive, naive, and erroneous; unprecedentedly
    given your stubbornness. Your persistent habit of making guesses,
    completely missing the point, topics, and characters, had regularly
    been shown to be widely erroneous. - I see you can't just stop your
    ineffective tries. It won't lead you anywhere.

    that my scheme isn't available in your favourite language.

    I have no "favourite language". (In a couple languages there's some
    concepts that I'd like to be more widely spread. - Not sure you're
    capable of understanding that and notice the blatant difference!)

    And you should meanwhile know that meaningless home-brewed languages
    are neither of general interest nor of mine; but you seem to have a
    persisting mental hindrance to understand what is easy understandable
    by others. - Just to be clear; I don't know that "my scheme" you're
    talking about is because I'm not interested in your posts about your
    personal tools.

    (I also suggest to become a bit more honest about your "achievement"
    with creating your tool unless it gets some minimum general relevance
    beyond your micro-ecosystem. - Why don't you advertise and offer your
    tools at any more appropriate place if you think they're so important,
    innovative, or generally useful?!)

    Janis

    lol, i told keith's team are funny asses..it needs some funcy answer:

    you say 'usefull', i tell "your mum is doin new school"

    https://www.youtube.com/watch?v=cumbkA5dGDI


    sorry becouse my bad english i am rather unable to catch some more
    subtle things in this anglish so maybe it should be

    you say 'usefull', i tell your mama is doin new school

    maybe this would be more appropriate

    (by crom.. i feel body pain again)
    (fir)


    this ilustrates this common topic:

    if youre not holding any rules of behaviour you may and in a crowd of
    annoying spammers like quite popular here..bot on oposite side
    you got a society of fellows who have so called sticks up their asses
    yet worse they oftan talk bulshit as stck up their as not guarantees
    talkin sense

    but those spamers also seem to have brain small as some seed
    so the normality lies somewehere in between imo
    (coz really this stick up the ass crowd is imo nonstandable spamers are
    also nonstandable)

    sadly usenet is not much large today it seems (which is very bad ofc)

    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From fir@3:633/10 to All on Sat Sep 12 12:40:30 2026
    fir pisze:
    fir pisze:
    fir pisze:
    Janis Papanagnou pisze:
    bart <bc@freeuk.com> writes:

    When you have to implement this stuff then you can't be sloppy.

    You demonstrated you can be extremely sloppy in your thinking and
    in your argumentation! That doesn't mean that you wouldn't be able
    to "write programs" ("this stuff"), for sure. - Another example of
    sloppy thinking and argumentation.

    Perhaps you're just jealous

    Your mindset is so primitive, naive, and erroneous; unprecedentedly
    given your stubbornness. Your persistent habit of making guesses,
    completely missing the point, topics, and characters, had regularly
    been shown to be widely erroneous. - I see you can't just stop your
    ineffective tries. It won't lead you anywhere.

    that my scheme isn't available in your favourite language.

    I have no "favourite language". (In a couple languages there's some
    concepts that I'd like to be more widely spread. - Not sure you're
    capable of understanding that and notice the blatant difference!)

    And you should meanwhile know that meaningless home-brewed languages
    are neither of general interest nor of mine; but you seem to have a
    persisting mental hindrance to understand what is easy understandable
    by others. - Just to be clear; I don't know that "my scheme" you're
    talking about is because I'm not interested in your posts about your
    personal tools.

    (I also suggest to become a bit more honest about your "achievement"
    with creating your tool unless it gets some minimum general relevance
    beyond your micro-ecosystem. - Why don't you advertise and offer your
    tools at any more appropriate place if you think they're so important, >>>> innovative, or generally useful?!)

    Janis

    lol, i told keith's team are funny asses..it needs some funcy answer:

    you say 'usefull', i tell "your mum is doin new school"

    https://www.youtube.com/watch?v=cumbkA5dGDI


    sorry becouse my bad english i am rather unable to catch some more
    subtle things in this anglish so maybe it should be

    you say 'usefull', i tell your mama is doin new school

    maybe this would be more appropriate

    (by crom.. i feel body pain again)
    (fir)


    this ilustrates this common topic:

    if youre not holding any rules of behaviour you may and in a crowd of annoying spammers like quite popular here..bot on˙ oposite side
    you got a society of fellows who have so called sticks up their asses
    yet worse they oftan talk bulshit as stck up their as not guarantees
    talkin sense

    but those spamers also seem to have brain small as some seed
    so the normality lies somewehere in between imo
    (coz really this stick up the ass crowd is imo nonstandable spamers are
    also nonstandable)

    sadly usenet is not much large today it seems (which is very bad ofc)

    im so sad over a dead tehnologies i dont even know (az those old ones
    weirdly often seem better thatthise modern)

    if the ? would become internet i would try to revitalise usenet
    encouraging to write 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 Sat Sep 12 11:55:27 2026
    On 12/09/2026 07:01, Janis Papanagnou wrote:
    bart <bc@freeuk.com> writes:

    When you have to implement this stuff then you can't be sloppy.

    You demonstrated you can be extremely sloppy in your thinking and
    in your argumentation! That doesn't mean that you wouldn't be able
    to "write programs" ("this stuff"), for sure. - Another example of
    sloppy thinking and argumentation.

    Perhaps you're just jealous

    Your mindset is so primitive, naive, and erroneous; unprecedentedly
    given your stubbornness. Your persistent habit of making guesses,
    completely missing the point, topics, and characters, had regularly
    been shown to be widely erroneous. - I see you can't just stop your ineffective tries. It won't lead you anywhere.

    that my scheme isn't available in your favourite language.

    I have no "favourite language". (In a couple languages there's some
    concepts that I'd like to be more widely spread. - Not sure you're
    capable of understanding that and notice the blatant difference!)

    And you should meanwhile know that meaningless home-brewed languages
    are neither of general interest nor of mine; but you seem to have a persisting mental hindrance to understand what is easy understandable
    by others. - Just to be clear; I don't know that "my scheme" you're
    talking about is because I'm not interested in your posts about your
    personal tools.

    Then you are blinkered. You should be able to evaluate and appreciate
    useful and innovate ideas by yourself, without relying on widespread
    adoption to tell you if they are good or bad.

    If, tomorrow, a major mainstream language introduced a module scheme
    just like mine, would you still hate it and think it useless, or would
    you suddenly change your mind?!

    Obviously not, because you are bigoted.


    (I also suggest to become a bit more honest about your "achievement"
    with creating your tool unless it gets some minimum general relevance
    beyond your micro-ecosystem. - Why don't you advertise and offer your
    tools at any more appropriate place if you think they're so important, innovative, or generally useful?!)
    I might have done that 35 years ago or more.

    For example, at one time my small company produced business computers.
    We designed everything about them (my job was taking care of the
    motherboard). We did the PCB layout, manufactured the actual PCBs, and populated the PCBS by hand, all in the UK (my boss owned two other small companies that took care of that).

    We even produced our own OS for it (via a 3rd associated company)!.

    Today's landscape is utterly different. Can you imagine one company in
    the UK producing dozens of computers per week compared with current mass-production in the far east that produces millions?

    The same with software, and with languages - no one is interested in 70s
    or 80s retro languages. And coding itself is being revolutionised.

    So, yes, my 'stuff' is a small bastion of languages and tools with a particular philosophy - small, fast, simple, effortless, self-contained, minimal and elegant. It is a continuation of that 1980s ethos where we
    did nearly everything in-house.

    That does not mean you have to look down your nose at what I do.

    If you look at fir's recent litany of complaints about C, wasn't it
    remarkable that most of those were 'fixed' in my systems language!

    Last year we had a discussion about Algol68 and specifically A68G, in comp.lang.misc. You were a proponent of that language and tool.

    I made some complaints about them that you and others didn't like. In
    the end I got fed and up signed off with this list of comparisons
    between them and my two personal languages.

    ----------------------------------------------------------------------

    (From comp.lang.misc, 'Removing influences from a language', posted
    13-Nov-25 22:39 GMT) ----------------------------------------------------------------------

    I have a systems language and a higher level dynamic one, that share the
    same syntax.

    So here are a number of those practical features, written with the
    systems language in mind, but many apply to both. A few at the end apply
    to the dynamic one only.

    This is why an old-fashioned, stilted language like Algol68 to me is now
    more of a curiosity; it's a toy.

    Features not natively present in Algol68 (that I know of, but of course
    I haven't read the full spec):

    * Fully case-insensitive

    * Module scheme

    * Namespaces

    * Scope-control attributes

    * Whole-program compilation (while having multiple modules!)

    * 'main' entry-point function that is automatically called

    * Mostly semicolon-free syntax (newline terminates statements
    unless they clearly continue onto the next line)

    * Full FFI with full support for machine-specific types

    * Full control of record layouts and alignment

    * Full out-of-order definitions for all entities

    * Textual code inclusion

    * String/binary file inclusion (embed any text or binary file as data)

    * Int is the main signed, numeric integer type, defaulting to 64 bits

    * Word is a 64-bit type used for unsigned numbers, and bit-patterns
    that may not be numeric (Haskell also has Int and Word types)

    * Label pointers and computed goto

    * Bit/Bitfield indexing ops for both l- and r-values

    * Bit-fields within records

    * CASE statement that sequentially checks a control expr against N
    possibilies (not the same as A68's 'case')

    * SWITCH statement that checks a control expr against N possibilies
    in parallel

    * SELECT statement that evaluates one of N possibilities according to an
    index 1..N. This is most like A68's 'case; it only exists as compact
    syntax

    * Simple enumerations

    * ENUMDATA defines a set of enumerations in parallel with corresponding
    data arrays

    * TABLEDATA defines parallel data arrays without any enums

    * SWAP operator

    * Chained comparisons: a = b = c; a <= b < c

    * 'IN' operator: if a in b..c, or if a in [b, c, d]

    * ++ and -- operators, including value-returning versions

    * Pointer arithmetic

    * Simple macros

    * Character constants: value such as 'A' up to 'ABCDEFGH' occupy one
    Word value

    * Multiple assignments: (a, b, c) := (x, y, z)

    * Multiple function return values: (a, b) := f(x)

    * Experimental piping operator: x -> F -> G means G(F(x))

    * Default function arguments

    * Named keyword arguments

    * For-loops that work over the values of a collection rather than an
    integer range

    * REPEAT-UNTIL

    * Looping CASE and SWITCH: DOCASE and DOSWITCH

    * Loop controls EXIT, REDO, NEXT can work with nested loops

    * ELSE clause for FOR-loops (as in Python)

    * Two special forms of DOSWITCH: DOSWITCHU uses multi-point dispatch
    code (to work better with branch prediction), of use within bytecode
    dispatch loops

    * And DOSWITCHX; needs extra setup code but can be 5% faster

    * Function tables which can be interrogated at runtime for function
    names and addresses

    * Built-in READ+READLN and PRINT+PRINTLN /statements/

    * Type-punning conversions including of r-values

    * Encapsulation: anything defined in a Record type can be accessed via
    the namespace scheme

    Following are dynamic language only:

    * Arbitrary precision decimal floating point arithmetic

    * Pascal-style bit-sets: ['A'..'Z', 'a'..'z']

    * Bit-arrays (actually of u1/u2/u4 elements) and bit pointers

    * Built-in hash-table arrays

    * 'IN' operator where RHS is a collection

    * Basic exceptions

    * First-class types and operators

    I haven't mentioned my tools or their performance. Let's just say the self-hosted systems compiler builds itself in 0.1 seconds, on the same
    machine that A68G builds in 35 seconds, if fast-tracked. They're nippy.


    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From fir@3:633/10 to All on Sat Sep 12 14:37:19 2026
    bart pisze:
    * Mostly semicolon-free syntax (newline terminates statements
    ˙ unless they clearly continue onto the next line)

    make it also ,-free becouse most (if not strictly any) , is not
    needed as space is a separtor ... i just like removed , and
    turned :: into , (as it was fee and better lookin)

    ";" advanced to be a paragraph(block) end sign

    also many () in function calls also not needed as i showed in previous examples


    as for this " " "," ";" syntax i just described it is probably and of
    the road here, cant do better/much beter robably (except maybe ; is not
    best looking so this sign eventually can change but the schem is like
    cleanest possible 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 Sat Sep 12 14:49:16 2026
    fir pisze:
    bart pisze:
    * Mostly semicolon-free syntax (newline terminates statements
    ˙˙ unless they clearly continue onto the next line)

    make it also ,-free becouse most (if not strictly any) , is not
    needed as space is a separtor ... i just like removed , and
    turned :: into , (as it was fee and better lookin)

    ˙";" advanced to be a paragraph(block) end sign

    also many () in function calls also not needed as i showed in previous examples


    as for this " " "," ";" syntax i just described it is probably and of
    the road here, cant do better/much beter robably (except maybe ; is not
    best looking so this sign eventually can change but the schem is like cleanest possible imo


    there is also an option of making blocks of blocks that would need
    more signs - or repeating one etc


    foo()
    a b c, d e f, g h;
    i j, k, l m n, o, p; ;

    v w, x;
    q, r s, t u; ;
    ;


    of course ;; not lokin good but something better here

    so this is the same as

    foo()
    {
    {{ {a b c, d e f, g h}
    {i j, k, l m n, o, p}}
    {{v w, x}
    {q, r s, t u} }
    }


    thus the logial lines in functions can be indexed foo[1][0][0] would be
    v x (v(x) call)



    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From fir@3:633/10 to All on Sat Sep 12 15:00:21 2026
    fir pisze:
    fir pisze:
    bart pisze:
    * Mostly semicolon-free syntax (newline terminates statements
    ˙˙ unless they clearly continue onto the next line)

    make it also ,-free becouse most (if not strictly any) , is not
    needed as space is a separtor ... i just like removed , and
    turned :: into , (as it was fee and better lookin)

    ˙˙";" advanced to be a paragraph(block) end sign

    also many () in function calls also not needed as i showed in previous
    examples


    as for this " " "," ";" syntax i just described it is probably and of
    the road here, cant do better/much beter robably (except maybe ; is
    not best looking so this sign eventually can change but the schem is
    like cleanest possible imo


    there is also an option of making blocks of blocks that would need
    more signs - or repeating one etc


    foo()
    ˙ a b c, d e f, g h;
    ˙ i j, k, l m n, o, p; ;

    ˙ v w, x;
    ˙ q, r s, t u;˙ ;
    ;


    of course ;; not lokin good but something better here

    so this is the same as

    foo()
    {
    ˙{{ {a b c, d e f, g h}
    ˙ {i j, k, l m n, o, p}}
    ˙ {{v w, x}
    ˙ {q, r s, t u} }
    }


    thus the logial lines in functions can be indexed foo[1][0][0] would be
    v x (v(x) call)

    the question is qhat with if-else and loops

    if(a) {b c} else {d e}

    btw if (as sorta is in c if(a) x; is replacement of if (a) {x;}
    then more logical it would be id(a) x; <--> if(a) {x} the if (a) {x;}
    has less sense


    in case of ifs it sees it probably shuld be

    { if(a) {b c} else {d e} }

    so one block is not divided here on 2 subblocks but there is also a 'rest'

    also that can be a loop though im not sure to this both

    in such case elements of normal c code probably also can be adressed

    though c codes are mostly shallow-wide not much vertical as blocks
    usually are mady by this if and for

    void DeallocFont(BMFont* f)
    {
    if(!f) return;

    for(int i = 0; i < 256; i++)
    {
    if(f->g[i].alpha)
    {
    free(f->g[i].alpha);
    f->g[i].alpha = NULL;
    }
    }

    free(f);

    }


    here DeallocFont.0 would be if(!f) return;

    DeallocFont.0.0 would be return

    (not sure as to "if(!f)" also index as subblock - maybe
    then 0,0 would be "if(!f) " soe 0.0.1 would be !f










    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From fir@3:633/10 to All on Sat Sep 12 15:23:42 2026
    bart pisze:
    * Multiple function return values: (a, b) := f(x)

    i asked ai which languages get tis in which year and it says
    (note ai may be not fully reliable, but it may be treated as some date
    whose are not know if fully reliable but worth maybe lookin at )

    J?zyk Od kiedy mniej wi?cej Przyk?ad
    CLU 1975 x, y := foo()
    Perl 1987 ($x, $y) = foo()
    Python 1991 x, y = foo()
    Lua 1993 x, y = foo()
    Ruby 1995 x, y = foo()
    Go 2009/2010 x, y := foo()
    Swift 2014 (x, y) = foo()
    JavaScript 2015 (ES6) [x, y] = foo()
    C# 2017 (C# 7) var (x, y) = foo()
    Rust 2015 dla destructuring let; 2022 dla assignment let (x, y) = foo()


    as i said back then i was starting lerning c afair 25 years ago
    maybe even exactly, - it was i remember like in a week thet was after
    WTC attack (so 25 years aggo exactly) - maybe 25 years form now

    maybe more on this story - in Toru? (whwre i was studying physics
    back then ) there was a chep books bookstore and i bought some old cheap
    book on "turbo c 2.0" (by bielinki?) i dont remember but has it still on
    my bookshelf - i literally was traveling in bus from toru? to my city
    when the radio in that bus give the news of WTC co its easy to memorize

    i alos remember i was not studying this book in toru? (i got no pc
    on my last place i rented i turu? (before we , me and my friend piotr,
    got some but we anly played adom on linuc there)

    so its sure i not learned it before wtc and i remember i was learning it
    quite afterwards

    this book was totally obsolete in 2001 but i find it very interesting as
    it covered C which before i got no idea on (only nknewed asembler,
    creepy basics and turbo pascel 7.0 or something)

    so when i was learnig c in this late 2001 thru 2002 and 2003 it was my begining (fortunate to remember in some way 2001 first year of knowing c
    and so on)

    so as to this above list I presently FOR MYSELF discovered that s should
    have it (returning 2 values ) was as i remember in 2003 (and i remember
    people back then didnt considered it as obvious)

    its maybe suprising perl and python had it so early but its also
    suprising javascript had it so late




    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From bart@3:633/10 to All on Sat Sep 12 14:24:41 2026
    On 12/09/2026 13:37, fir wrote:
    bart pisze:
    * Mostly semicolon-free syntax (newline terminates statements
    ˙˙ unless they clearly continue onto the next line)

    make it also ,-free becouse most (if not strictly any) , is not
    needed as space is a separtor ...

    Removing intra-line commas is not really practical. Even if technically
    some code can be parsed without it, humans have difficulty.

    Some structure is needed. Take this parameter list with commas:

    (a b c, d e)

    'a' and 'd' are types; b, c, e are parameter names. Without the commas
    it would just be:

    (a b c d e)

    (In my language, user-defined types are not resolved into types until
    after parsing. The parser relies on structure to determine which names
    are types.)

    While a function call like F(a + b, -1, sin c) ('sin' is an operator),
    would become:

    F(a + b -1 sin c)

    It all runs together, and here there is also an ambiguity between "b,
    -1" and "b - 1".

    However, I /have/ looked at interline commas: this is where you have a
    long list of data initialisers, one per line. There it would be less of
    a problem as newline acts as separator.

    But I still found it troublesome as the parser needs to keep track of
    whether it's a semicolon- or comma-separated context.

    (This is partly implemented, but as I can't remember in which language
    or context, I find it easier to just write the commas.)

    i just like removed , and
    turned :: into , (as it was fee and better lookin)


    Really? So C's 'std::cout' becomes 'std,cout'? That looks totally wrong.

    also many () in function calls also not needed as i showed in previous examples

    Minimalist just doesn't work, sorry. It might in a language like Haskell
    which has special rules (and features like currying), but that is not
    the kind of language I want to write.



    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From fir@3:633/10 to All on Sat Sep 12 15:44:07 2026
    bart pisze:
    On 12/09/2026 13:37, fir wrote:
    bart pisze:
    * Mostly semicolon-free syntax (newline terminates statements
    ˙˙ unless they clearly continue onto the next line)

    make it also ,-free becouse most (if not strictly any) , is not
    needed as space is a separtor ...

    Removing intra-line commas is not really practical. Even if technically
    some code can be parsed without it, humans have difficulty.

    Some structure is needed. Take this parameter list with commas:

    ˙˙ (a b c, d e)

    'a' and 'd' are types; b, c, e are parameter names. Without the commas
    it would just be:

    ˙˙ (a b c d e)


    its becouse you give examples with not know what it mean if it would be

    int b c float e its more clear (fully clear imo

    though im was not saying on this case - as i said , works in a place of
    ; (its a "logical line" seperator so it work like ";" in c where the c
    usages of "," are ust removed

    i mean , removed
    ; replaced by ,



    (In my language, user-defined types are not resolved into types until
    after parsing. The parser relies on structure to determine which names
    are types.)

    While a function call like F(a + b, -1, sin c) ('sin' is an operator),
    would become:

    ˙˙ F(a + b -1 sin c)


    F a+b -1 sin c

    is clear imo 9though better is to use separate - sign for neg values
    not subtraction)

    in above i mean probably its good to take you baf write

    foo arg arg arg foo arg arg

    i mean "only one function acll in logical line so you would need

    foo arg arg arg, foo arg arg

    to satisfy this rule so if

    you see this

    F a+b -1 sin c

    you know its one function call thus sin c is argument






    It all runs together, and here there is also an ambiguity between "b,
    -1" and "b - 1".

    However, I /have/ looked at interline commas: this is where you have a
    long list of data initialisers, one per line. There it would be less of
    a problem as newline acts as separator.

    But I still found it troublesome as the parser needs to keep track of whether it's a semicolon- or comma-separated context.

    (This is partly implemented, but as I can't remember in which language
    or context, I find it easier to just write the commas.)

    i just like removed , and
    turned :: into , (as it was fee and better lookin)



    sorry i meant ; not :: (shift didnt worked )

    Really? So C's 'std::cout' becomes 'std,cout'? That looks totally wrong.

    also many () in function calls also not needed as i showed in previous
    examples

    Minimalist just doesn't work, sorry. It might in a language like Haskell which has special rules (and features like currying), but that is not
    the kind of language I want to write.



    there is alos to use ' optionally i mean some may use them in ()

    like

    print a b c

    may use

    (print a b c) //optionally

    or

    print (a b c) //optionally

    or
    print (a,b,c) //optionally

    aventually

    thet would probbaly not collide with general "bare naked" {s n j, s d f,
    s d}
    syntax


    im not sure if allowing print(a b c) could not cause slight collisions
    if so some slight changes there would need be here but in worst case
    it would be disalowed but probably i would prefer in worst case
    doing meaningful space it is not eventually allowing

    print (a b c)

    in that case (at worst ) but maybe its not needed, i would need to check 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 Sat Sep 12 07:45:12 2026
    bart wrote:
    On 12/09/2026 07:01, Janis Papanagnou wrote:
    bart <bc@freeuk.com> writes:

    When you have to implement this stuff then you can't be sloppy.

    You demonstrated you can be extremely sloppy in your thinking and
    in your argumentation! That doesn't mean that you wouldn't be able
    to "write programs" ("this stuff"), for sure. - Another example of
    sloppy thinking and argumentation.

    Perhaps you're just jealous

    Your mindset is so primitive, naive, and erroneous; unprecedentedly
    given your stubbornness. Your persistent habit of making guesses,
    completely missing the point, topics, and characters, had regularly
    been shown to be widely erroneous. - I see you can't just stop your
    ineffective tries. It won't lead you anywhere.

    that my scheme isn't available in your favourite language.

    I have no "favourite language". (In a couple languages there's some
    concepts that I'd like to be more widely spread. - Not sure you're
    capable of understanding that and notice the blatant difference!)

    And you should meanwhile know that meaningless home-brewed languages
    are neither of general interest nor of mine; but you seem to have a
    persisting mental hindrance to understand what is easy understandable
    by others. - Just to be clear; I don't know that "my scheme" you're
    talking about is because I'm not interested in your posts about your
    personal tools.

    Then you are blinkered. You should be able to evaluate and appreciate
    useful and innovate ideas by yourself, without relying on widespread adoption to tell you if they are good or bad.

    Oh no, Janis is a punch card kid. He has to conform or else the
    university will dock his punch card time.

    If, tomorrow, a major mainstream language introduced a module scheme
    just like mine, would you still hate it and think it useless, or would
    you suddenly change your mind?!

    Obviously not, because you are bigoted.


    (I also suggest to become a bit more honest about your "achievement"
    with creating your tool unless it gets some minimum general relevance
    beyond your micro-ecosystem. - Why don't you advertise and offer your
    tools at any more appropriate place if you think they're so important,
    innovative, or generally useful?!)
    I might have done that 35 years ago or more.

    For example, at one time my small company produced business computers.
    We designed everything about them (my job was taking care of the motherboard). We did the PCB layout, manufactured the actual PCBs, and populated the PCBS by hand, all in the UK (my boss owned two other small companies that took care of that).

    We even produced our own OS for it (via a 3rd associated company)!.

    Today's landscape is utterly different. Can you imagine one company in
    the UK producing dozens of computers per week compared with current mass-production in the far east that produces millions?

    Not to mention, Janis is showing his small-mindedness (perhaps a total
    lack of MBA) that lower prices create greater demand. In Janis' world, increasing the prices at your company leads to greater lurve and
    happiness with no repercussions whatsoever. It's all about price for
    Janis, not price * units sold. He had to spend all his time at
    university waiting for the punch card system and found no time for
    economics electives.


    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From fir@3:633/10 to All on Sat Sep 12 15:53:31 2026
    fir pisze:
    bart pisze:
    On 12/09/2026 13:37, fir wrote:
    bart pisze:
    * Mostly semicolon-free syntax (newline terminates statements
    ˙˙ unless they clearly continue onto the next line)

    make it also ,-free becouse most (if not strictly any) , is not
    needed as space is a separtor ...

    Removing intra-line commas is not really practical. Even if
    technically some code can be parsed without it, humans have difficulty.

    Some structure is needed. Take this parameter list with commas:

    ˙˙˙ (a b c, d e)

    'a' and 'd' are types; b, c, e are parameter names. Without the commas
    it would just be:

    ˙˙˙ (a b c d e)


    its becouse you give examples with not know what it mean if it would be

    int b c float e its more clear (fully clear imo

    though im was not saying˙ on this case - as i said , works in a place of
    ; (its a "logical line" seperator so it work like ";" in c where the c usages of "," are ust removed

    i mean , removed
    ; replaced by ,



    (In my language, user-defined types are not resolved into types until
    after parsing. The parser relies on structure to determine which names
    are types.)

    While a function call like F(a + b, -1, sin c) ('sin' is an operator),
    would become:

    ˙˙˙ F(a + b -1 sin c)


    F a+b -1 sin c

    is clear imo˙ 9though better is to use separate - sign for neg values
    not subtraction)

    in above i mean probably its good to take you baf write

    foo arg arg arg foo arg arg

    i mean "only one function acll in logical line so you would need

    foo arg arg arg, foo arg arg

    to satisfy this rule so if

    you see this

    F a+b -1 sin c

    you know its one function call thus sin c is argument






    It all runs together, and here there is also an ambiguity between "b,
    -1" and "b - 1".

    However, I /have/ looked at interline commas: this is where you have a
    long list of data initialisers, one per line. There it would be less
    of a problem as newline acts as separator.

    But I still found it troublesome as the parser needs to keep track of
    whether it's a semicolon- or comma-separated context.

    (This is partly implemented, but as I can't remember in which language
    or context, I find it easier to just write the commas.)

    i just like removed , and
    turned :: into , (as it was fee and better lookin)



    sorry i meant ; not :: (shift didnt worked )

    Really? So C's 'std::cout' becomes 'std,cout'? That looks totally wrong.

    also many () in function calls also not needed as i showed in
    previous examples

    Minimalist just doesn't work, sorry. It might in a language like
    Haskell which has special rules (and features like currying), but that
    is not the kind of language I want to write.



    there is alos to use ' optionally i mean some may use them in ()

    like

    print a b c

    may use

    (print a b c) //optionally

    or

    print (a b c)˙ //optionally

    or
    print (a,b,c) //optionally

    aventually

    thet would probbaly not collide with general "bare naked" {s n j, s d f,
    s d}
    syntax


    im not sure if allowing print(a b c) could not cause slight collisions
    if so some slight changes there would need be here but in worst case
    it would be disalowed but probably i would prefer in worst case
    doing meaningful space it is not eventually allowing

    print (a b c)

    in that case (at worst ) but maybe its not needed, i would need to
    check it



    you probbaly mean such cases

    foo a b c (d f) e

    note if c is a function and it takes 2 arguments its
    not clear if its

    foo a b c (d f) e

    or
    foo a b c((d f) e )

    if d e are values then it probably ishould be first but if
    d is a function it probably should be the second


    generally i dont see a clear problems here, somebody would need to give
    me some problematic example coz i dont see any (not seeing ofr sure i inspected all bot seemd to ma like it iis ok or close to okay)











    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From fir@3:633/10 to All on Sat Sep 12 16:05:37 2026
    fir pisze:

    F a+b -1 sin c

    this second minus is in fact needed so normally

    this above is f a+b-2 sin(c)

    unicode as usually instead of having something cruciallu usful provides
    soem weirdos here

    this above with -2 not subtraction would be f a+b ?2 sin(c)

    but meybe somethin could be find

    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From fir@3:633/10 to All on Sat Sep 12 16:16:30 2026
    fir pisze:
    fir pisze:

    F a+b -1 sin c

    this second minus is in fact needed so normally

    this above is f a+b-2 sin(c)

    unicode as usually instead of having something cruciallu usful provides
    soem weirdos here

    this above with -2 not subtraction would be˙ f a+b ?2 sin(c)

    but meybe somethin could be find

    unicode has such options

    2-2*?2
    2-2*?2
    2-2*?2
    2-2*?2

    no one looks much good in seamonkey reader i use , this third looks
    standable though but thats depend on font i guess

    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From fir@3:633/10 to All on Sat Sep 12 17:20:14 2026
    fir pisze:
    fir pisze:

    F a+b -1 sin c

    this second minus is in fact needed so normally

    this above is f a+b-2 sin(c)

    unicode as usually instead of having something cruciallu usful provides
    soem weirdos here

    this above with -2 not subtraction would be˙ f a+b ?2 sin(c)

    but meybe somethin could be find


    note (1) imo you should not look if its easy for human to resolve it
    only if compiler can resolve it

    human can add some spaces and () "eventually" so what the problem

    more over trained people would understand it as they understand present
    c which is also quite cryptic if you dont understand it


    and note (2) id compiler is to understod given formula it had
    definitions so he knows if given ab c d e if function variable
    type or something else as it need be defined (if its not defined he recgognizes it too - as undefined symbol

    mor eto say thse comples syntaxes are in fact rare imo, most common is
    pure stuf like

    print "abjhabj", drawline x y p q 0x777

    so most impoortant it has this especially clean (as i got)

    second more common is probbaly

    setpixel x*b+c y*g+h rand_color 0x889977 0xaabbcc

    imo its also clean if you know what setpixel
    and rand_color take

    set pixel takes 3 and randcolor2 so its not any ambiguity for compiler

    and human may add () in many places here

    setpixel(x*b+c y*g+ (rand_color(0x889977 0xaabbcc))

    though this traditional form im not sure

    imo its probably clearer to write

    setpixel x*b+c y*g+h (rand_color 0x889977 0xaabbc)

    than traditional

    setpixel (x*b+c y*g+h rand_color(0x889977 0xaabbc))

    this is becouse (f a a) is one thing where f(a a) is one things and
    (a a) is liek lESS one thing, but probbaly this form can be allowed for tradition (though im not sure as it seems bad)



    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From bart@3:633/10 to All on Sat Sep 12 17:08:18 2026
    On 12/09/2026 14:44, fir wrote:
    bart pisze:
    On 12/09/2026 13:37, fir wrote:
    bart pisze:
    * Mostly semicolon-free syntax (newline terminates statements
    ˙˙ unless they clearly continue onto the next line)

    make it also ,-free becouse most (if not strictly any) , is not
    needed as space is a separtor ...

    Removing intra-line commas is not really practical. Even if
    technically some code can be parsed without it, humans have difficulty.

    Some structure is needed. Take this parameter list with commas:

    ˙˙˙ (a b c, d e)

    'a' and 'd' are types; b, c, e are parameter names. Without the commas
    it would just be:

    ˙˙˙ (a b c d e)


    its becouse you give examples with not know what it mean if it would be

    int b c float e its more clear (fully clear imo

    Sure, but what happens when someone /wants/ to have user-define types?
    So in general it is ambiguous.

    In C you can also have a parameter list which has only types, no
    parameter names. If that is still a feature, then:

    (a, b, c, d);

    can be assumed (by the reader) to be all types. But this:

    (a b c d)

    is more ambiguous; how many parameters are there: is it 4 (abcd are all types); 3 (a is a type, bcd are names), or 2 (ac are types, bd are
    names)? Other combinations may be possible.


    though im was not saying˙ on this case - as i said , works in a place
    of ; (its a "logical line" seperator so it work like ";" in c where the
    c usages of "," are ust removed

    i mean , removed
    ; replaced by ,



    (In my language, user-defined types are not resolved into types until
    after parsing. The parser relies on structure to determine which names
    are types.)

    While a function call like F(a + b, -1, sin c) ('sin' is an operator),
    would become:

    ˙˙˙ F(a + b -1 sin c)


    F a+b -1 sin c


    Significant white space now? Come pm, what sort of crazy language is
    this going to be?!

    But since this is a fantasy language anyway that is never going to be implemented, then sure, leave out whatever you want. But it will be a
    terrible language to work with.

    is clear imo˙ 9though better is to use separate - sign for neg values
    not subtraction)

    in above i mean probably its good to take you baf write

    foo arg arg arg foo arg arg

    Users can make their own identifiers so it could be this:

    arg foo foo foo arg foo foo

    In general a compiler will see:

    a b c d e f g

    Seven consecutive identifiers.

    i mean "only one function acll in logical line so you would need

    foo arg arg arg, foo arg arg

    to satisfy this rule so if

    you see this

    F a+b -1 sin c

    you know its one function call thus sin c is argument


    I'm sorry, but this stuff needs to be COMPLETELY AMBIGUOUS. Someone
    should INSTANTLY be able to know what is intended, rather than waste
    time trying to infer it. This is supposed to be the source code of some program, not a puzzle!

    You can make it unambiguous by using commas and parentheses, and
    EVERYONE will understand what is being expressed.

    What exactly are trying to achieve here: saving a few seconds of typing
    but then spending ten times as long trying to understand the code, or
    1000 times as long trying to debug all the subtle bugs that have crept in?

    I know this is a fantasy, but aren't you interested in practicalities at
    all?


    i just like removed , and
    turned :: into , (as it was fee and better lookin)



    sorry i meant ; not :: (shift didnt worked )

    std;cout isn't much better! Both "::" and "." are commonly used for this purpose.
    im not sure if allowing print(a b c) could not cause slight collisions
    if so some slight changes there would need be here but in worst case
    it would be disalowed but probably i would prefer in worst case
    doing meaningful space it is not eventually allowing

    print (a b c)
    How sure are you that two user identifiers can never be adjacent?

    What about operators that can be both unary and binary? A further example:

    a b * c * d

    Is this a(b * c * d), or a(b, *c * d), or (b, *c, *d) etc?

    Please don't say that you have to work it out by hunting for the
    definitions; as I said this should not be a puzzle.


    --- 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 Sat Sep 12 10:53:33 2026
    bart wrote:

    What exactly are trying to achieve here: saving a few seconds of typing
    but then spending ten times as long trying to understand the code, or
    1000 times as long trying to debug all the subtle bugs that have crept in?

    That's the spirit! fir is trying to achieve a nonsensical language, just
    like your line here (which I guess is missing the word 'you'). Playing
    along, I see you are typing nonsense to placate him!


    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From fir@3:633/10 to All on Sat Sep 12 19:23:02 2026
    bart pisze:
    On 12/09/2026 14:44, fir wrote:
    bart pisze:
    On 12/09/2026 13:37, fir wrote:
    bart pisze:
    * Mostly semicolon-free syntax (newline terminates statements
    ˙˙ unless they clearly continue onto the next line)

    make it also ,-free becouse most (if not strictly any) , is not
    needed as space is a separtor ...

    Removing intra-line commas is not really practical. Even if
    technically some code can be parsed without it, humans have difficulty.

    Some structure is needed. Take this parameter list with commas:

    ˙˙˙ (a b c, d e)

    'a' and 'd' are types; b, c, e are parameter names. Without the
    commas it would just be:

    ˙˙˙ (a b c d e)


    its becouse you give examples with not know what it mean if it would be

    int b c float e its more clear (fully clear imo

    Sure, but what happens when someone /wants/ to have user-define types?
    So in general it is ambiguous.

    In C you can also have a parameter list which has only types, no
    parameter names. If that is still a feature, then:

    ˙ (a, b, c, d);

    can be assumed (by the reader) to be all types. But this:

    ˙ (a b c d)

    is more ambiguous; how many parameters are there: is it 4 (abcd are all types); 3 (a is a type, bcd are names), or 2 (ac are types, bd are
    names)? Other combinations may be possible.


    though im was not saying˙ on this case - as i said , works in a place
    of ; (its a "logical line" seperator so it work like ";" in c where
    the c usages of "," are ust removed

    i mean , removed
    ; replaced by ,



    (In my language, user-defined types are not resolved into types until
    after parsing. The parser relies on structure to determine which
    names are types.)

    While a function call like F(a + b, -1, sin c) ('sin' is an
    operator), would become:

    ˙˙˙ F(a + b -1 sin c)


    F a+b -1 sin c


    Significant white space now? Come pm, what sort of crazy language is
    this going to be?!

    But since this is a fantasy language anyway that is never going to be implemented, then sure, leave out whatever you want. But it will be a terrible language to work with.

    is clear imo˙ 9though better is to use separate - sign for neg values
    not subtraction)

    in above i mean probably its good to take you baf write

    foo arg arg arg foo arg arg

    Users can make their own identifiers so it could be this:

    ˙ arg foo foo foo arg foo foo

    In general a compiler will see:

    ˙ a b c d e f g

    this is your very serious problem here that you assume 'unlearned' human should understand it, compiler must understand it... Im not sure hovever
    how to explain it to you that this your dogmate is wrong

    you know what you talk also fits to c you also neeeded to learn what
    given construction mean here its just the same jus construction have
    less ,,, () stuf




    kompiler knows what given symbols are..if it make sense it will compile
    it if not he will not if you make some complex stuff with a net of
    functions like

    f1 a f2 f3 f4 a a f5 f6

    compiler know which function takes how many arguments
    and will resolve it to fit

    im not sure if there is any disimbiguity here or none


    if you know one tell me and i will tell a rule to resolve it
    (as it may be resolved by some rule

    if yu worry on humen radibilit y you just add parentheses and you
    end up at worst in your initial form..but there is simply a form to
    do it much cleaner and many use will use the clean lightweight 'naked'
    form (no gothic clothes)






    Seven consecutive identifiers.

    i mean "only one function acll in logical line so you would need

    foo arg arg arg, foo arg arg

    to satisfy this rule so if

    you see this

    F a+b -1 sin c

    you know its one function call thus sin c is argument


    I'm sorry, but this stuff needs to be COMPLETELY AMBIGUOUS. Someone
    should INSTANTLY be able to know what is intended, rather than waste
    time trying to infer it. This is supposed to be the source code of some program, not a puzzle!


    it is totally ambigious , one confusion is only related to the problem
    that -2 uses the same sign as 4-2 (this is in fact nonstandable that
    mean you need give unicode sign (and in worse case if comeone couldnt
    probbaly something like this meaningful space here but that would be
    bad ofc in that case - though generally spaces are meningfull its not
    that you can skipp all spaces in c... in fact in my version they are
    more meaningfull than in c becouse you cant delete much more of them but
    this kind of meaningfulnes as 4-2 against 4 -2 is obviously wrong
    (but some other better probably may exist)

    when i see this its totally clear to me


    F a+b -1 sin c

    F tahes 2 args a+b-1 and sin c its only badly written like

    F (a +b -1 , sin( c ) )

    you may also badly write

    You can make it unambiguous by using commas and parentheses, and
    EVERYONE will understand what is being expressed.

    What exactly are trying to achieve here: saving a few seconds of typing
    but then spending ten times as long trying to understand the code, or
    1000 times as long trying to debug all the subtle bugs that have crept in?


    imo it is both faster to read and type arso cleaner


    I know this is a fantasy, but aren't you interested in practicalities at all?




    its not a fantasy language this is just scientific outcome on possible language syntax so it so much fantasy as 2+2=4


    its not a fantasy its a RESULT

    (such things name is RESULTS (rezultaty in polish), outcome



    i just like removed , and
    turned :: into , (as it was fee and better lookin)



    sorry i meant ; not :: (shift didnt worked )

    std;cout isn't much better! Both "::" and "." are commonly used for this purpose.
    im not sure if allowing print(a b c) could not cause slight collisions
    if so some slight changes there would need be here but in worst case
    it would be disalowed but probably i would prefer in worst case
    doing meaningful space it is not eventually allowing

    print (a b c)
    How sure are you that two user identifiers can never be adjacent?

    What about operators that can be both unary and binary? A further example:

    ˙ a b * c * d

    Is this a(b * c * d), or a(b, *c * d), or (b, *c, *d) etc?

    Please don't say that you have to work it out by hunting for the definitions; as I said this should not be a puzzle.


    no worry , definitions wouldnt help here

    this above is obviously non possible you cant have unary and binary
    here (as far as it seems, i may be maybe wrong)

    a*b must be binary if *b would be unary then it mean you have

    a *b so its ambiguity , so there some additional rule would need to be
    used at least

    rule can be

    a*b // is binary
    a(*b) //is unary
    (a*)b //is unary

    this touches some problem becouse it blocks a(b) syntax which eventually
    could be usefull, but it eventually may be seen not much usefull
    as i see () more like separators not 'calling' operator
    (it only be blocked for those types of ab though not necessary for
    fiunction calls

    there is also option to use this space as a seperator ..this kind of mmeaningfull spaces i use here all time for example in a b c d
    apaces are meaningfull coz its not ab c d

    so a *b wouldnt be considered good idea but a (*b) being different than
    a(*b) may be (but VERY eventually)






    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From fir@3:633/10 to All on Sat Sep 12 19:34:05 2026
    bart pisze:
    Sure, but what happens when someone /wants/ to have user-define types?
    So in general it is ambiguous.

    In C you can also have a parameter list which has only types, no
    parameter names. If that is still a feature, then:

    ˙ (a, b, c, d);

    can be assumed (by the reader) to be all types. But this:

    ˙ (a b c d)

    is more ambiguous; how many parameters are there: is it 4 (abcd are all types); 3 (a is a type, bcd are names), or 2 (ac are types, bd are
    names)? Other combinations may be possible.

    this one i dont understand whats difference id someone uses like
    structure nameinstead of int?

    no difference

    and if ou see such thing as int int a b foo float
    do i ask you how many type names are there? how many wariables and how
    many function names?

    note in code if it is not obfuscated names are meaningfull, type names
    are not popular ther repeat and you know them generally function names
    are usualy verbs (i write is mostly in big letter, variables i
    personally always write low leter)

    some functions i write low letter but those very qshort very quick usage
    one like sin strcmp print - only few things like that


    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From fir@3:633/10 to All on Sat Sep 12 19:39:34 2026
    fir pisze:
    bart pisze:
    Sure, but what happens when someone /wants/ to have user-define types?
    So in general it is ambiguous.

    In C you can also have a parameter list which has only types, no
    parameter names. If that is still a feature, then:

    ˙˙ (a, b, c, d);

    can be assumed (by the reader) to be all types. But this:

    ˙˙ (a b c d)

    is more ambiguous; how many parameters are there: is it 4 (abcd are
    all types); 3 (a is a type, bcd are names), or 2 (ac are types, bd are
    names)? Other combinations may be possible.

    this one i dont understand whats difference id someone uses like
    structure nameinstead of int?

    no difference

    and if ou see such thing as int int a b foo float
    do i ask you how many type names are there? how many wariables and how
    many function names?

    note in code if it is not obfuscated names are meaningfull, type names
    are not popular ther repeat and you know them generally function names
    are usualy verbs (i write is mostly in big letter, variables i
    personally always write low leter)

    some functions i write low letter but those very qshort very quick usage
    one like sin strcmp print - only few things like that




    obviously your not obliged to understand that (i mean this new naked/no
    gothic clothes) syntax

    its maybe better people dont understand that it maybe mnimalises chanse someone would take that valueable syntax results and implement it and
    not adress (credt) me an propar author of this stuff

    its not that those results are not to take, they may be taken but
    thecredits should be done just to make historical acuracy of some
    solutions not spreading lies (and filling history with lies (yawn) i
    think its understood


    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From bart@3:633/10 to All on Sat Sep 12 18:58:01 2026
    On 12/09/2026 18:23, fir wrote:
    bart pisze:

    In general a compiler will see:

    ˙˙ a b c d e f g

    this is your very serious problem here that you assume 'unlearned' human should understand it, compiler must understand it...

    This is the problem: a compiler might not understand it.

    To do so, first requires that those symbols have been previously
    defined, and here, that they have also been resolved /while parsing/.

    This is the case for C as it is now. But remember you were annoyed at
    having to declare things in advance? So it might be that 'a' is a
    function that is defined later on.

    In that case, it won't know how to parse this properly. It will need to
    build a tentative AST (perhaps a concrete syntax tree or 'CST'), and
    later transform into a proper AST.

    But that still leaves the problem of any reader of the code being
    bamboozled.

    It might worth remembering that a HLL is supposed to be easier to write
    and read than assembly or machine code. Having this extra burden for
    virtually no benefit is pointless.


    you know what you talk also fits to c you also neeeded to learn what
    given construction mean here its just the same jus construction have
    less ,,, () stuf

    Well, we don't know the rest of your language. I mentioned one point above.

    C itself still has structure: you will never see 7 user identifiers
    together (unless someone goes overboard with macros, and that would be
    very poor too).





    kompiler knows what given symbols are..if it make sense it will compile
    it if not he will not if you make some complex stuff with a net of
    functions like

    f1 a f2 f3 f4 a a f5 f6


    compiler know which function takes how many arguments
    and will resolve it to fit

    OK, a compiler might be able to do so if:

    * There are no variadic functions

    * The languages doesn't have default argument values (BTW this feature
    would be a million times more useful than being able to leave out all punctuation)

    * The function doesn't use an unspecified parameter list (this was a
    feature of C but C23 may have deprecated that)

    * You sort out the clashes between unary and binary operators.

    * All names have either been previously defined, or whole extras has
    been done for this purpose.

    But that is not the point: a human reader does not want that extra burden.



    im not sure if there is any disimbiguity here or none


    if you know one tell me and i will tell a rule to resolve it
    (as it may be resolved by some rule

    if yu worry on humen radibilit y you just add parentheses and you
    end up at worst in your initial form

    It's not that simple; if you see:

    a ( ... )

    does that '(' mean the whole argument list is contained, or just the
    first argument of several? How much lookahead is needed to make it work?

    ..but there is simply a form to
    do it much cleaner and many use will use the clean lightweight 'naked'
    form (no gothic clothes)

    when i see this its totally clear to me

    OK, here is a fragment of code by itself:

    a b c d

    Tell me what it means. You don't have access to the rest of the program,
    or you haven't got time to hunt for the definitions in 100,000 lines of
    code spread across 28 headers in 12 folders.

    Now here is the same fragment but with those 'useless' commas and
    parentheses:

    a(b(c, d))

    Does that help?

    Yes, there might technically be redundancy, but that is a useful feature
    in a programming language: it can catch mistakes.



    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From fir@3:633/10 to All on Sat Sep 12 20:15:08 2026
    fir pisze:

    no worry , definitions wouldnt help here

    this above is obviously non possible˙ you cant have unary and binary
    here (as far as it seems, i may be maybe wrong)

    a*b must be binary if *b would be unary then it mean you have

    a *b so its ambiguity , so there some additional rule would need to be
    used at least

    rule can be

    a*b˙ // is binary
    a(*b) //is unary
    (a*)b //is unary

    this touches some problem becouse it blocks a(b) syntax which eventually could be usefull, but it eventually may be seen not much usefull
    as i see () more like separators not˙ 'calling' operator
    (it only be blocked for those types of ab though not necessary for
    fiunction calls

    there is also option to use this space as a seperator ..this kind of mmeaningfull spaces i use here all time for example in a b c d
    apaces are meaningfull coz its not ab c d

    so a *b wouldnt be considered good idea but a (*b) being different than a(*b) may be (but VERY eventually)


    overally the question if to allow a(b) as a syntax is by chance good
    question

    it is mostly eventually needed from traditional reasons

    f(a) [4 chars] is also maybe shorter than (f a)[5 chars] but longer than
    f a [3 chars]
    some coud say fthat f(a)f(a)f(a)f(a) wins over (f a)(f a)(f a) and
    equals with f a f a f a f a f a, hard to say at this moment


    f(a) probabably could be allowed but if so probably tha lack of space
    would be meaningfull at least for some types

    i cant say yet for sure in this case.. problem is imo

    f(a) is in fact more misleading than helpfull

    some really do like

    print("ass " foo(x y) sin(x))




    over more logical

    print "ass" (foo x y)(sin x)



    over a cleaner


    print "ass" foo x y sin x


    esp as free spaces may be added for clarity

    print "ass" foo x y sin x

    there ere many unicode eventuals separators for optional usage
    for someone who need it in some cases but not for general usage imo but
    an option


    not this above but something could ba taken but
    1) FOR OPTIONAL USAGE ONLY
    2) NOT , MUST BE SOMETHING OTHER


    for example those circles (bullets) i generally find more suitable for denoting definitions

    ? foo
    x = 28
    ? bar
    print "ataa"
    ? zoo { sin x}

    some liek python keyword def but shorter

    ? ya!



    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From fir@3:633/10 to All on Sat Sep 12 20:35:29 2026
    bart pisze:>
    a(b(c, d))

    Does that help?

    not much honestly - if youre so much in hole you can find
    definitions..as you say you are

    two terrible mistakes you do

    1) you somewhat assume that definitions are not pesent - all definitions
    are present - if definitions are not present it would not compile


    2) you talk about this human reader its not a problem

    you may add those parenthesis optionally... and if someone not added it
    blame him

    though as i said i would add the () different way

    not a(b(c, d))

    but

    a (b c d)



    you anyway should use meaningdull names in this examples becouse names
    carry an information
    and with this examples you compare obfuscated code context - in which by chance my form also wins (which is fortunate)

    im not saying this is no more cryptic i just say its not cryptic if you
    know what it is and know the rules

    this form is simpler a(b(c, d))
    than mine a b c d becouse in mine form this a b c d may be just more
    things than in this a(b(c, d))


    in your form a can be a variable or type b also c cant be a function d
    cant be a function

    its very bad becouse in my form it can



    (note i not yet call about all thos syntaxes as i mosly only chosen
    the function call form (also nested) and simple expresions like a=b+3

    eben for such simple expresions ike

    int a b c
    or int a b c float e d f

    alos not fully resolved finction headers

    im not yet sure so some things are potentially open, yet

    BUT IM RATHER COMPLETELY SURE

    that this form

    DrawLine x y p q color

    for basic function call IS TOO GOD TO NOT TAKE IT -

    co this is FIXED..its offical, as someone could say

    you cant just not take such good things
    (saying you as a mode of speach, i mean someone, its too good to not
    take it)













    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From fir@3:633/10 to All on Sat Sep 12 20:46:18 2026
    fir pisze:
    a (b c d)

    this btw ilustrates some problem

    a (b c d)

    probably must be allowed here but you CANT ASSUME

    that a (b c d) is function cal generally

    YOU MAY ASSUME in there newline after that but if there is oor example x
    after that

    a (b c d) x


    this part a (b c d) dont mean its function call -
    if a takes one argument its function call but if two

    a (b c d) x

    is function call

    so not always a ( b c d) is function call

    could probably enforce that

    a(b c d)


    may be function call but im not sure if its good idea


    i dont see a problem with this crazy helps to reader like he would have
    no brain, btter use meaningfull names to know what is what


    combination of 4 not meaningful names in programing is not usual i would say





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

    combination of 4 not meaningful names in programing is not usual i would
    say



    i think i need to break this conversation as for at least till monday
    (coz i get a bit weary)..could eventuall add something but not
    necessary, but longer discusion of this type at least after some break

    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From bart@3:633/10 to All on Sat Sep 12 22:16:34 2026
    On 12/09/2026 19:35, fir wrote:
    bart pisze:>
    ˙˙˙ a(b(c, d))

    Does that help?

    not much honestly - if youre so much in hole you can find
    definitions..as you say you are

    two terrible mistakes you do

    1) you somewhat assume that definitions are not pesent - all definitions
    are present - if definitions are not present it would not compile


    2) you talk about this human reader its not a problem

    you may add those parenthesis optionally... and if someone not added it blame him

    though as i said i would add the () different way

    not˙˙ a(b(c, d))

    but

    ˙ a (b c d)



    you anyway should use meaningdull names in this examples becouse names
    carry an information

    You want to design a language that /depends/ on the user devising
    suitable names in order to deduce the /shape/ of the code? That is the
    whole point of using a structured HLL in the first place!

    Try this experiment: take a C source file and eliminate all ()s and
    commas. Replace with a space if necessary to separate alphanumeric tokens.

    Compare with the original and see which one is easier to work with.

    (With C, missing () will give problems with macro definitions and casts,
    among other things.)

    Note that the code will still have braces. I suggest a better aim is to eliminate most braces. The should be no need to ever see '} else {'
    instead of just 'else'.

    In fact, if C is the start point, there is a huge amount that can be
    done to end up with a cleaner language while not doing away with useful redundancy.

    This is a C program:

    #include <stdio.h>
    #include <math.h>

    int main() {
    for (int i = 1; i <= 10; ++i) {
    printf("%d %f\n", i, sqrt(i));
    puts("----------");
    }
    }

    A little contrived, but no matter because the same contrivance is here
    in my systems language:

    proc main =
    for i to 10 do
    println i, sqrt i
    println "----------"
    end
    end

    The C has 53 tokens (58 if you include all that gubbins inside the first string).

    My version has only 17 tokens, nearly 70% fewer. And yet it still uses
    the parentheses and commas that you're trying to eliminate (not many in
    this example, but that is part of my point).

    Of C's 53/58 tokens, 16 are parentheses, colons and semicolons. Removing
    those would still leave 37/42 tokens. If you also disregard those
    '#includes', a one-time cost, it would still be 23/27! (And would result
    in ambiguous code unless you add lots of new rules.)

    So I think you're going about this the wrong way: getting rid of
    /useful/ punctuation symbols while still keeping the useless ones,
    resulting in a more restricted language with new rules.


    DrawLine x y p q color

    for basic function call IS TOO GOD TO NOT TAKE IT -

    This will break as soon as you try something more complicated.

    If you want that, then try a PostScript-style stack language:

    x y p q colour DrawLine

    Here, parentheses and commas are not needed.

    The problem is you don't want to write 10s of 1000s of lines in this
    style; you want a conventional syntax which is easier to follow.

    BTW here is a draw-line routine in my scripting language:

    proc gxline(w, x, y, ?x2, ?y2) ...

    It takes either one point or two. It is these optional args that would
    make it hard to figure out a call like this:

    gxline w a b c d

    Is this gxline(w, a, b, c, d), or is it gxline(w, a, b(c, d))? In this
    dynamic language, b might be a variable containing a function reference.



    --- 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 Sat Sep 12 15:40:54 2026
    bart wrote:

    BTW here is a draw-line routine in my scripting language:

    ˙ proc gxline(w, x, y, ?x2, ?y2) ...

    It takes either one point or two. It is these optional args that would
    make it hard to figure out a call like this:

    ˙˙ gxline w a b c d

    Is this gxline(w, a, b, c, d), or is it gxline(w, a, b(c, d))? In this dynamic language, b might be a variable containing a function reference.


    Why don't you ask Keith? He will tell you a cat was medium size, and so
    it is gxline(w,a,b(c,d)). Finally, the man has a use. Can you build a
    compiler with Keith at its center to make these disambiguations? Rumor
    has it there is an AI which is one person answering questions, but has
    quite a backlog. Speed may be an issue.


    --- 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 13 10:15:57 2026
    bart pisze:
    A little contrived, but no matter because the same contrivance is here
    in my systems language:

    ˙˙ proc main =
    ˙˙˙˙˙˙ for i to 10 do
    ˙˙˙˙˙˙˙˙˙˙ println i, sqrt i
    ˙˙˙˙˙˙˙˙˙˙ println "----------"
    ˙˙˙˙˙˙ end
    ˙˙ end

    () and ; removed which is good but you alsoe need to remove keywords
    and this one ' and it will be ok



    --- 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 13 10:27:15 2026
    fir pisze:
    bart pisze:
    A little contrived, but no matter because the same contrivance is here
    in my systems language:

    ˙˙˙ proc main =
    ˙˙˙˙˙˙˙ for i to 10 do
    ˙˙˙˙˙˙˙˙˙˙˙ println i, sqrt i
    ˙˙˙˙˙˙˙˙˙˙˙ println "----------"
    ˙˙˙˙˙˙˙ end
    ˙˙˙ end

    () and ; removed which is good but you alsoe need˙ to remove keywords
    and this one ' and it will be ok



    something like - you need a billet to mark definitions ..next one may be
    used by another definition but may also put empty one


    ? main
    ?10
    println ? sqrt ?
    println "----------"

    ?




    --- 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 13 10:39:15 2026
    fir pisze:
    fir pisze:
    bart pisze:
    A little contrived, but no matter because the same contrivance is
    here in my systems language:

    ˙˙˙ proc main =
    ˙˙˙˙˙˙˙ for i to 10 do
    ˙˙˙˙˙˙˙˙˙˙˙ println i, sqrt i
    ˙˙˙˙˙˙˙˙˙˙˙ println "----------"
    ˙˙˙˙˙˙˙ end
    ˙˙˙ end

    () and ; removed which is good but you alsoe need˙ to remove keywords
    and this one ' and it will be ok



    something like - you need a billet to mark definitions ..next one may be used by another definition but may also put empty one


    ˙? main
    ˙˙˙ ?10
    ˙˙˙˙˙˙ println ? sqrt ?
    ˙˙˙˙˙˙ println "----------"

    ˙?


    btw i asked ai about years of languages dont need ";" at the endo of
    line (as i said ai is not totally reliable but out of curiosity)


    a od jak dawna w jezykach programowanie jest to ze mozna ominac koncowy
    ; ktory np w c jest wymagany

    To zale?y od j?zyka, bo pomijanie ko?cowego ; pojawia?o si? ju? bardzo wcze?nie.

    Najciekawsza chronologia:

    J?zyk Rok Jak to dzia?a
    Python 1991 ; w og˘le nie jest potrzebny do ko?ca instrukcji ? koniec linii j? ko?czy
    Visual Basic 1991 brak ; na ko?cu instrukcji
    Ruby 1995 koniec linii zwykle ko?czy instrukcj?
    JavaScript 1995 automatyczne wstawianie ?rednika (ASI)
    Go 2009 kompilator automatycznie wstawia ; w okre?lonych miejscach Swift 2014 ; opcjonalny
    Kotlin 2016 ; opcjonalny
    Rust 2010/2015 ; ma znaczenie sk?adniowe i cz?sto jest wymagany, wi?c to
    inny przypadek


    --- 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 Sun Sep 13 10:50:30 2026
    On 12/09/2026 19:58, bart wrote:

    (Snipping lots of good points about language design - I don't want to
    discuss fir's hypothetical language, but I can still give you a little
    more information on a C point.)


    * The function doesn't use an unspecified parameter list (this was a
    feature of C but C23 may have deprecated that)

    The use of non-prototype function declarations (including implicit ones)
    was marked as an "obsolescent" feature in C90. (That is, if I
    understand correctly, it was not actually deprecated but was planned to
    be deprecated in the near future). C23 skipped deprecation entirely and removed it from the language. (I think most C programmers see that as absurdly slow timing from the C standards committee and C compiler implementers. I only know of one C expert who thought non-prototype
    function declarations were useful to keep around, and I don't think he
    ever gave a good reason for that.)


    --- 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 13 10:30:58 2026
    On 13/09/2026 09:15, fir wrote:
    bart pisze:
    A little contrived, but no matter because the same contrivance is here
    in my systems language:

    ˙˙˙ proc main =
    ˙˙˙˙˙˙˙ for i to 10 do
    ˙˙˙˙˙˙˙˙˙˙˙ println i, sqrt i
    ˙˙˙˙˙˙˙˙˙˙˙ println "----------"
    ˙˙˙˙˙˙˙ end
    ˙˙˙ end

    () and ; removed which is good but you alsoe need˙ to remove keywords
    and this one ' and it will be ok
    The same code runs as-is in my scripting language, but that also allows
    this version:

    for i to 10 do
    ? i, ûi
    ? "-"*10
    od

    Any better? (The "-"*10 works above too but it was two extra tokens! The
    'û' is an alias for 'sqrt' and was added for fun.)

    There used to be a compact form of loop too which may have looked like this:

    (i:10 || ?i, ûi; "-"*10)

    That's great. But now imagine 1000 lines full of such gobbledygook.

    It sounds like your ideal language would be APL, if is not 'clean' and
    'clear' that you're after, but 'minimal' and 'cryptic'.

    The first version above is the best balance in my view. You /want/ some mixture of keywords and symbols.

    In any case, in a typical program, only 1/3 of alphanumerics of
    keywords; the rest will still be user-identifiers.

    --- 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 13 11:47:43 2026
    bart pisze:
    On 13/09/2026 09:15, fir wrote:
    bart pisze:
    A little contrived, but no matter because the same contrivance is
    here in my systems language:

    ˙˙˙ proc main =
    ˙˙˙˙˙˙˙ for i to 10 do
    ˙˙˙˙˙˙˙˙˙˙˙ println i, sqrt i
    ˙˙˙˙˙˙˙˙˙˙˙ println "----------"
    ˙˙˙˙˙˙˙ end
    ˙˙˙ end

    () and ; removed which is good but you alsoe need˙ to remove keywords
    and this one ' and it will be ok
    The same code runs as-is in my scripting language, but that also allows
    this version:

    ˙ for i to 10 do
    ˙˙˙˙˙ ? i, ûi
    ˙˙˙˙˙ ? "-"*10
    ˙ od

    Any better? (The "-"*10 works above too but it was two extra tokens! The
    'û' is an alias for 'sqrt' and was added for fun.)

    There used to be a compact form of loop too which may have looked like
    this:

    ˙(i:10 || ?i, ûi; "-"*10)

    That's great. But now imagine 1000 lines full of such gobbledygook.

    It sounds like your ideal language would be APL, if is not 'clean' and 'clear' that you're after, but 'minimal' and 'cryptic'.

    The first version above is the best balance in my view. You /want/ some mixture of keywords and symbols.

    In any case, in a typical program, only 1/3 of alphanumerics of
    keywords; the rest will still be user-identifiers.


    i gave you example - its only cryptic if you dont know what it means




    --- 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 13 11:53:55 2026
    fir pisze:
    bart pisze:
    On 13/09/2026 09:15, fir wrote:
    bart pisze:
    A little contrived, but no matter because the same contrivance is
    here in my systems language:

    ˙˙˙ proc main =
    ˙˙˙˙˙˙˙ for i to 10 do
    ˙˙˙˙˙˙˙˙˙˙˙ println i, sqrt i
    ˙˙˙˙˙˙˙˙˙˙˙ println "----------"
    ˙˙˙˙˙˙˙ end
    ˙˙˙ end

    () and ; removed which is good but you alsoe need˙ to remove keywords
    and this one ' and it will be ok
    The same code runs as-is in my scripting language, but that also
    allows this version:

    ˙˙ for i to 10 do
    ˙˙˙˙˙˙ ? i, ûi
    ˙˙˙˙˙˙ ? "-"*10
    ˙˙ od

    Any better? (The "-"*10 works above too but it was two extra tokens!
    The 'û' is an alias for 'sqrt' and was added for fun.)

    There used to be a compact form of loop too which may have looked like
    this:

    ˙˙(i:10 || ?i, ûi; "-"*10)

    That's great. But now imagine 1000 lines full of such gobbledygook.

    It sounds like your ideal language would be APL, if is not 'clean' and
    'clear' that you're after, but 'minimal' and 'cryptic'.

    The first version above is the best balance in my view. You /want/
    some mixture of keywords and symbols.

    In any case, in a typical program, only 1/3 of alphanumerics of
    keywords; the rest will still be user-identifiers.


    i gave you example - its only cryptic if you dont know what it means


    consider for example french or polish language its totally cryptic until
    you will learn it... not to say you want to understand it without
    definitions

    overally this discussin ended i think at least as for few months,
    cant continue becouse you repeat the same things which i got the same
    answer (ori talk tehe sama and you rpeat with the same answer)

    repeating is not necassary ;c


    --- 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 13 11:26:58 2026
    On 13/09/2026 10:53, fir wrote:
    fir pisze:
    bart pisze:

    It sounds like your ideal language would be APL, if is not 'clean'
    and 'clear' that you're after, but 'minimal' and 'cryptic'.

    The first version above is the best balance in my view. You /want/
    some mixture of keywords and symbols.

    In any case, in a typical program, only 1/3 of alphanumerics of
    keywords; the rest will still be user-identifiers.


    i gave you example - its only cryptic if you dont know what it means


    consider for example french or polish language its totally cryptic until
    you will learn it...


    That is not your aim. That appears to be to start with a language that
    you know perfectly well, but remove all punctuation, capitalisation and structure, and half the words. But to what purpose; because you're too
    lazy to type?

    not to say you want to understand it without
    definitions

    So an APL (or J or K) program is never cryptic because all you have to
    do is learn it? If only I'd thought of that!

    The same applies to Assembly I guess. And machine code?


    overally this discussin ended i think at least as for few months,
    cant continue becouse you repeat the same things

    And you keep repeating the same nonsense. What is your endpoint: a
    program that can be expressed in one byte?


    --- 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 13 12:32:34 2026
    David Brown pisze:
    On 12/09/2026 19:58, bart wrote:

    (Snipping lots of good points about language design - I don't want to discuss fir's hypothetical language, but I can still give you a little
    more information on a C point.)


    * The function doesn't use an unspecified parameter list (this was a
    feature of C but C23 may have deprecated that)

    The use of non-prototype function declarations (including implicit ones)
    was marked as an "obsolescent" feature in C90.˙ (That is, if I
    understand correctly, it was not actually deprecated but was planned to
    be deprecated in the near future).˙ C23 skipped deprecation entirely and removed it from the language.˙ (I think most C programmers see that as absurdly slow timing from the C standards committee and C compiler implementers.˙ I only know of one C expert who thought non-prototype function declarations were useful to keep around, and I don't think he
    ever gave a good reason for that.)


    i was thinking about possible usage of this thinghbut dont see clearly many..its maybe weird as it seem tit should be some

    more probably i see as to thios global tmp ram record
    which you cn at least use to pass values among

    f(); b(); with no passing arguments //via this tmp global ram



    --- 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 13 12:37:54 2026
    bart pisze:
    On 13/09/2026 10:53, fir wrote:
    fir pisze:
    bart pisze:

    It sounds like your ideal language would be APL, if is not 'clean'
    and 'clear' that you're after, but 'minimal' and 'cryptic'.

    The first version above is the best balance in my view. You /want/
    some mixture of keywords and symbols.

    In any case, in a typical program, only 1/3 of alphanumerics of
    keywords; the rest will still be user-identifiers.


    i gave you example - its only cryptic if you dont know what it means


    consider for example french or polish language its totally cryptic
    until you will learn it...


    That is not your aim. That appears to be to start with a language that
    you know perfectly well, but remove all punctuation, capitalisation and structure, and half the words. But to what purpose; because you're too
    lazy to type?

    ˙not to say you want to understand it without
    definitions

    So an APL (or J or K) program is never cryptic because all you have to
    do is learn it? If only I'd thought of that!

    The same applies to Assembly I guess. And machine code?


    apl i dont know but ofc it applies to assembly but x86 assembly is
    terribly flawed
    x86 assembly is like c++


    overally this discussin ended i think at least as for few months,
    cant continue becouse you repeat the same things

    And you keep repeating the same nonsense. What is your endpoint: a
    program that can be expressed in one byte?


    my goal is to make it cleanest possible
    and also make thsi sintax more powerfull - it is "carrying" a lot more "weight" (semantic weight).. i men where short sentences may expres much meaning

    --- 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 13 12:47:15 2026
    fir pisze:
    bart pisze:
    On 13/09/2026 10:53, fir wrote:
    fir pisze:
    bart pisze:

    It sounds like your ideal language would be APL, if is not 'clean'
    and 'clear' that you're after, but 'minimal' and 'cryptic'.

    The first version above is the best balance in my view. You /want/
    some mixture of keywords and symbols.

    In any case, in a typical program, only 1/3 of alphanumerics of
    keywords; the rest will still be user-identifiers.


    i gave you example - its only cryptic if you dont know what it means


    consider for example french or polish language its totally cryptic
    until you will learn it...


    That is not your aim. That appears to be to start with a language that
    you know perfectly well, but remove all punctuation, capitalisation
    and structure, and half the words. But to what purpose; because you're
    too lazy to type?

    ˙˙not to say you want to understand it without
    definitions

    So an APL (or J or K) program is never cryptic because all you have to
    do is learn it? If only I'd thought of that!

    The same applies to Assembly I guess. And machine code?


    apl i dont know but ofc it applies to assembly but x86 assembly is
    terribly flawed
    x86 assembly is like c++


    overally this discussin ended i think at least as for few months,
    cant continue becouse you repeat the same things

    And you keep repeating the same nonsense. What is your endpoint: a
    program that can be expressed in one byte?


    my goal is to make it cleanest possible
    and also make thsi sintax more powerfull - it is "carrying" a lot more "weight" (semantic weight).. i men where short sentences may expres much meaning

    this example is quite clean and weighty

    ? main
    ?10
    println ? sqrt ?
    println "----------"

    ?

    esp this ?10 is clean and weighty i got a lot of problems with this
    becouse x10 eventually worked but has terrible disadwantage xa is not
    standable (a is variable value say 100) but unicode resolves a lot of
    problems coz ?a work

    NOTE this all now seem obvious but before discovering this what seems
    obvious LATER BEFORE this all conclusions was VERY FAR form obvious

    im saying this becouse i thing that people will take some outcome and
    not adress its orygination..all this conclusion i take are oryginal at
    least in a sense it is not copied from someo other source (except the
    most common typical knowledge base)

    (not saying that some solutions i use by chance were already invented
    but often in some different contextes and not fully)

    even seint the fact some just should take unicode was not obvious not to mention many other things





    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Ike Naar@3:633/10 to All on Sun Sep 13 10:53:30 2026
    On 2026-09-12, bart <bc@freeuk.com> wrote:
    Note that the code will still have braces. I suggest a better aim is to eliminate most braces. The should be no need to ever see '} else {'
    instead of just 'else'.

    There can be a difference; for example (assume <stdio.h> included):

    if (0) { if (1) puts("foo"); else puts("bar"); }

    if (0) { if (1) puts("foo"); } else { puts("bar"); }

    The first line will print nothing; the second one will print "bar".

    --- 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 13 12:55:31 2026
    fir pisze:
    fir pisze:
    bart pisze:
    On 13/09/2026 10:53, fir wrote:
    fir pisze:
    bart pisze:

    It sounds like your ideal language would be APL, if is not 'clean' >>>>>> and 'clear' that you're after, but 'minimal' and 'cryptic'.

    The first version above is the best balance in my view. You /want/ >>>>>> some mixture of keywords and symbols.

    In any case, in a typical program, only 1/3 of alphanumerics of
    keywords; the rest will still be user-identifiers.


    i gave you example - its only cryptic if you dont know what it means >>>>>

    consider for example french or polish language its totally cryptic
    until you will learn it...


    That is not your aim. That appears to be to start with a language
    that you know perfectly well, but remove all punctuation,
    capitalisation and structure, and half the words. But to what
    purpose; because you're too lazy to type?

    ˙˙not to say you want to understand it without
    definitions

    So an APL (or J or K) program is never cryptic because all you have
    to do is learn it? If only I'd thought of that!

    The same applies to Assembly I guess. And machine code?


    apl i dont know but ofc it applies to assembly but x86 assembly is
    terribly flawed
    x86 assembly is like c++


    overally this discussin ended i think at least as for few months,
    cant continue becouse you repeat the same things

    And you keep repeating the same nonsense. What is your endpoint: a
    program that can be expressed in one byte?


    my goal is to make it cleanest possible
    and also make thsi sintax more powerfull - it is "carrying" a lot more
    "weight" (semantic weight).. i men where short sentences may expres
    much meaning

    this example is quite clean and weighty

    ˙ ? main
    ˙˙˙˙ ?10
    ˙˙˙˙˙˙˙ println ? sqrt ?
    ˙˙˙˙˙˙˙ println "----------"

    ˙ ?


    its not fully resolved yet as questions may ofc arise and need answer
    for example if i use ? as an index then ? as ana infinite loop is taken?
    maybe yes maybe not (need answer)


    also it rises question is tab?=10 okay as an array acces tab[x]=10

    also if to allow spaces and so on

    ? tab_size
    tab ? = 10

    but i know such things may be resolved more or less so it not deny such
    clean base





    esp this ?10 is clean and weighty i got a lot of problems with this
    becouse x10 eventually worked but has terrible disadwantage xa is not standable (a is variable value say 100) but unicode resolves a lot of problems coz ?a work

    NOTE this all now seem obvious but before discovering this what seems obvious LATER BEFORE this all conclusions was VERY FAR form obvious

    im saying this becouse i thing that people will take some outcome and
    not adress its orygination..all this conclusion i take are oryginal at
    least in a sense it is not copied from someo other source (except the
    most common typical knowledge base)

    (not saying that some solutions i use by chance were already invented
    but often in some different contextes and not fully)

    even seint the fact some just should take unicode was not obvious not to mention many other 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 Sun Sep 13 13:11:17 2026
    fir pisze:
    esp this ?10 is clean and weighty i got a lot of problems with this
    becouse x10 eventually worked but has terrible disadwantage xa is not standable (a is variable value say 100) but unicode resolves a lot of problems coz ?a work

    NOTE this all now seem obvious but before discovering this what seems obvious LATER BEFORE this all conclusions was VERY FAR form obvious


    you by chance illustrate this problem

    you in fact has notably more feel in this things as average comp.lang.c
    user (as seen the fight with you statements often true but you itself
    when confronted with better sollution not only not take it but also
    fights with it

    this illustrates how indeed far from this solution are nearly all people
    ;c (so rare i dont know none who is close but maybe some are hidden in
    some mountains ;c wtill my solutions are oryginal as i dont know no one
    who is doin something close as me 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 Sun Sep 13 05:29:33 2026
    bart wrote:
    On 13/09/2026 10:53, fir wrote:
    fir pisze:
    bart pisze:

    It sounds like your ideal language would be APL, if is not 'clean'
    and 'clear' that you're after, but 'minimal' and 'cryptic'.

    The first version above is the best balance in my view. You /want/
    some mixture of keywords and symbols.

    In any case, in a typical program, only 1/3 of alphanumerics of
    keywords; the rest will still be user-identifiers.


    i gave you example - its only cryptic if you dont know what it means


    consider for example french or polish language its totally cryptic
    until you will learn it...


    That is not your aim. That appears to be to start with a language that
    you know perfectly well, but remove all punctuation, capitalisation and structure, and half the words. But to what purpose; because you're too
    lazy to type?

    ˙not to say you want to understand it without
    definitions

    So an APL (or J or K) program is never cryptic because all you have to
    do is learn it? If only I'd thought of that!

    The same applies to Assembly I guess. And machine code?


    overally this discussin ended i think at least as for few months,
    cant continue becouse you repeat the same things

    And you keep repeating the same nonsense. What is your endpoint: a
    program that can be expressed in one byte?

    He wants to compress the language, metaphor a plum, into a prune that
    has much reduced.

    It is the same way with a newsgroup when the warlord Lane W has
    compressed all the shitheads, David Brown, Keith, bart, and the rest
    except I guess the fellows who are in the mood, when they all conspire
    by email to not respond to anything he writes. It is at such a time that
    he declares victory. As I roll over yet another group in the 97 I have subjugated to my rule and made complacent, a tear drips from my eye. C,
    such a beautiful language, yet what hypocrites such as David Brown
    defending it. Really, nothing personal? I beg to differ. Under my boot,
    a serpent crawls out of the skull of another victim.

    --- 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 13 13:43:13 2026
    Lane W pisze:
    bart wrote:
    On 13/09/2026 10:53, fir wrote:
    fir pisze:
    bart pisze:

    It sounds like your ideal language would be APL, if is not 'clean'
    and 'clear' that you're after, but 'minimal' and 'cryptic'.

    The first version above is the best balance in my view. You /want/
    some mixture of keywords and symbols.

    In any case, in a typical program, only 1/3 of alphanumerics of
    keywords; the rest will still be user-identifiers.


    i gave you example - its only cryptic if you dont know what it means


    consider for example french or polish language its totally cryptic
    until you will learn it...


    That is not your aim. That appears to be to start with a language that
    you know perfectly well, but remove all punctuation, capitalisation
    and structure, and half the words. But to what purpose; because you're
    too lazy to type?

    ˙˙not to say you want to understand it without
    definitions

    So an APL (or J or K) program is never cryptic because all you have to
    do is learn it? If only I'd thought of that!

    The same applies to Assembly I guess. And machine code?


    overally this discussin ended i think at least as for few months,
    cant continue becouse you repeat the same things

    And you keep repeating the same nonsense. What is your endpoint: a
    program that can be expressed in one byte?

    He wants to compress the language, metaphor a plum, into a prune that
    has much reduced.

    It is the same way with a newsgroup when the warlord Lane W has
    compressed all the shitheads, David Brown, Keith, bart, and the rest
    except I guess the fellows who are in the mood, when they all conspire
    by email to not respond to anything he writes. It is at such a time that
    he declares victory. As I roll over yet another group in the 97 I have subjugated to my rule and made complacent, a tear drips from my eye. C,
    such a beautiful language, yet what hypocrites such as David Brown
    defending it. Really, nothing personal? I beg to differ. Under my boot,
    a serpent crawls out of the skull of another victim.

    no worry its hard to answer this becouse its hard to know what exactly
    tis is about but it sometimes have some points (you will need hovever
    care not to overdo it..becouse as i said when commenting some people
    with sticks up in their asses some such type coments are fun but if
    there is to much of cross boundering there may haos os spam do appear
    and that is harmfull


    --- 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 13 13:46:48 2026
    On 13/09/2026 11:53, Ike Naar wrote:
    On 2026-09-12, bart <bc@freeuk.com> wrote:
    Note that the code will still have braces. I suggest a better aim is to
    eliminate most braces. The should be no need to ever see '} else {'
    instead of just 'else'.

    There can be a difference; for example (assume <stdio.h> included):

    if (0) { if (1) puts("foo"); else puts("bar"); }

    if (0) { if (1) puts("foo"); } else { puts("bar"); }

    The first line will print nothing; the second one will print "bar".


    This illustrates my point; first some Pascal:

    if cond then begin s1; s2 end else begin s3; s4 end

    C is the same but uses braces, and semicolons are terminators:

    if (cond) { s1; s2; } else { s3; s4; }

    One has 'end else begin', the other has '} else {'.

    However the Pascal version can be improved; since 'then' and 'else' can
    act as block delimiters:

    if cond then s1; s2 end else s3; s4 end

    Only the final block in a chain (eg. if-else-if) needs the 'end'
    terminator. And now 'else' is by itself.

    Unfortunately this doesn't transfer well to C:

    if (cond) s1; s2; else s3; s4; }

    The () around 'cond' are needed as the ')' separates cond and s1 (fir
    doesn't not appreciate this point; he thinks it is fine for statements
    and expressions to run together provided that there is a way to infer
    where one logically ends and the other starts).

    The trouble is that lone, unbalanced } at the end.

    So it would need a bigger change. But then that's what fir is doing.
    (He's never going to get there, but there's no harm in humouring him.)

    --- 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 13 15:21:10 2026
    bart pisze:
    On 13/09/2026 11:53, Ike Naar wrote:
    On 2026-09-12, bart <bc@freeuk.com> wrote:
    Note that the code will still have braces. I suggest a better aim is to
    eliminate most braces. The should be no need to ever see '} else {'
    instead of just 'else'.

    There can be a difference; for example (assume <stdio.h> included):

    ˙˙˙˙ if (0) { if (1) puts("foo");˙˙ else˙˙ puts("bar"); }

    ˙˙˙˙ if (0) { if (1) puts("foo"); } else { puts("bar"); }

    The first line will print nothing; the second one will print "bar".


    This illustrates my point; first some Pascal:

    ˙ if cond then begin s1; s2 end else begin s3; s4 end

    C is the same but uses braces, and semicolons are terminators:

    ˙ if (cond) { s1; s2; } else { s3; s4; }

    One has 'end else begin', the other has '} else {'.

    However the Pascal version can be improved; since 'then' and 'else' can
    act as block delimiters:

    ˙ if cond then s1; s2 end else s3; s4 end

    Only the final block in a chain (eg. if-else-if) needs the 'end'
    terminator. And now 'else' is by itself.

    Unfortunately this doesn't transfer well to C:

    ˙ if (cond) s1; s2; else s3; s4; }

    The () around 'cond' are needed as the ')' separates cond and s1 (fir doesn't not appreciate this point; he thinks it is fine for statements
    and expressions to run together provided that there is a way to infer
    where one logically ends and the other starts).

    The trouble is that lone, unbalanced } at the end.

    So it would need a bigger change. But then that's what fir is doing.
    (He's never going to get there, but there's no harm in humouring him.)


    what you consider problems is so siple i dont even think on it


    as to ifs syntax i am yet not sure

    some like this may be considered but its not much good loking
    though is sorta logical

    x<10 ? x++>5
    ? more_than_five
    ? less_than_six
    ? do_nothing

    those ? ale also sorta redundant

    x<10 x++>5 more_than_five ? less_than_six ? do_nothing




    can optionally ad parenthesis or braces for clarity

    x<10 (x++>5 more_than_five ? less_than_six) ? do_nothing

    x<10 {x++>5 more_than_five ? less_than_six } ? do_nothing



    but im not fully convinced

    --- 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 13 15:31:16 2026
    On 13/09/2026 14:21, fir wrote:
    bart pisze:
    On 13/09/2026 11:53, Ike Naar wrote:
    On 2026-09-12, bart <bc@freeuk.com> wrote:
    Note that the code will still have braces. I suggest a better aim is to >>>> eliminate most braces. The should be no need to ever see '} else {'
    instead of just 'else'.

    There can be a difference; for example (assume <stdio.h> included):

    ˙˙˙˙ if (0) { if (1) puts("foo");˙˙ else˙˙ puts("bar"); }

    ˙˙˙˙ if (0) { if (1) puts("foo"); } else { puts("bar"); }

    The first line will print nothing; the second one will print "bar".


    This illustrates my point; first some Pascal:

    ˙˙ if cond then begin s1; s2 end else begin s3; s4 end

    C is the same but uses braces, and semicolons are terminators:

    ˙˙ if (cond) { s1; s2; } else { s3; s4; }

    One has 'end else begin', the other has '} else {'.

    However the Pascal version can be improved; since 'then' and 'else'
    can act as block delimiters:

    ˙˙ if cond then s1; s2 end else s3; s4 end

    Only the final block in a chain (eg. if-else-if) needs the 'end'
    terminator. And now 'else' is by itself.

    Unfortunately this doesn't transfer well to C:

    ˙˙ if (cond) s1; s2; else s3; s4; }

    The () around 'cond' are needed as the ')' separates cond and s1 (fir
    doesn't not appreciate this point; he thinks it is fine for statements
    and expressions to run together provided that there is a way to infer
    where one logically ends and the other starts).

    The trouble is that lone, unbalanced } at the end.

    So it would need a bigger change. But then that's what fir is doing.
    (He's never going to get there, but there's no harm in humouring him.)


    what you consider problems is so siple i dont even think on it


    as to ifs syntax i am yet not sure

    some like this may be considered but its not much good loking
    though is sorta logical

    x<10 ? x++>5
    ˙˙˙˙˙˙ ?˙ more_than_five
    ˙˙˙˙˙˙ ? less_than_six
    ˙˙˙ ? do_nothing

    Try: if 5 < x < 10.



    --- 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 13 16:34:09 2026
    bart pisze:
    On 13/09/2026 14:21, fir wrote:
    bart pisze:
    On 13/09/2026 11:53, Ike Naar wrote:
    On 2026-09-12, bart <bc@freeuk.com> wrote:
    Note that the code will still have braces. I suggest a better aim
    is to
    eliminate most braces. The should be no need to ever see '} else {'
    instead of just 'else'.

    There can be a difference; for example (assume <stdio.h> included):

    ˙˙˙˙ if (0) { if (1) puts("foo");˙˙ else˙˙ puts("bar"); }

    ˙˙˙˙ if (0) { if (1) puts("foo"); } else { puts("bar"); }

    The first line will print nothing; the second one will print "bar".


    This illustrates my point; first some Pascal:

    ˙˙ if cond then begin s1; s2 end else begin s3; s4 end

    C is the same but uses braces, and semicolons are terminators:

    ˙˙ if (cond) { s1; s2; } else { s3; s4; }

    One has 'end else begin', the other has '} else {'.

    However the Pascal version can be improved; since 'then' and 'else'
    can act as block delimiters:

    ˙˙ if cond then s1; s2 end else s3; s4 end

    Only the final block in a chain (eg. if-else-if) needs the 'end'
    terminator. And now 'else' is by itself.

    Unfortunately this doesn't transfer well to C:

    ˙˙ if (cond) s1; s2; else s3; s4; }

    The () around 'cond' are needed as the ')' separates cond and s1 (fir
    doesn't not appreciate this point; he thinks it is fine for
    statements and expressions to run together provided that there is a
    way to infer where one logically ends and the other starts).

    The trouble is that lone, unbalanced } at the end.

    So it would need a bigger change. But then that's what fir is doing.
    (He's never going to get there, but there's no harm in humouring him.)


    what you consider problems is so siple i dont even think on it


    as to ifs syntax i am yet not sure

    some like this may be considered but its not much good loking
    though is sorta logical

    x<10 ? x++>5
    ˙˙˙˙˙˙˙ ?˙ more_than_five
    ˙˙˙˙˙˙˙ ? less_than_six
    ˙˙˙˙ ? do_nothing

    Try: if 5 < x < 10.


    why? its the same


    5<x<10 ?




    --- 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 13 16:58:50 2026
    fir pisze:
    bart pisze:
    On 13/09/2026 14:21, fir wrote:
    bart pisze:
    On 13/09/2026 11:53, Ike Naar wrote:
    On 2026-09-12, bart <bc@freeuk.com> wrote:
    Note that the code will still have braces. I suggest a better aim >>>>>> is to
    eliminate most braces. The should be no need to ever see '} else {' >>>>>> instead of just 'else'.

    There can be a difference; for example (assume <stdio.h> included):

    ˙˙˙˙ if (0) { if (1) puts("foo");˙˙ else˙˙ puts("bar"); }

    ˙˙˙˙ if (0) { if (1) puts("foo"); } else { puts("bar"); }

    The first line will print nothing; the second one will print "bar".


    This illustrates my point; first some Pascal:

    ˙˙ if cond then begin s1; s2 end else begin s3; s4 end

    C is the same but uses braces, and semicolons are terminators:

    ˙˙ if (cond) { s1; s2; } else { s3; s4; }

    One has 'end else begin', the other has '} else {'.

    However the Pascal version can be improved; since 'then' and 'else'
    can act as block delimiters:

    ˙˙ if cond then s1; s2 end else s3; s4 end

    Only the final block in a chain (eg. if-else-if) needs the 'end'
    terminator. And now 'else' is by itself.

    Unfortunately this doesn't transfer well to C:

    ˙˙ if (cond) s1; s2; else s3; s4; }

    The () around 'cond' are needed as the ')' separates cond and s1
    (fir doesn't not appreciate this point; he thinks it is fine for
    statements and expressions to run together provided that there is a
    way to infer where one logically ends and the other starts).

    The trouble is that lone, unbalanced } at the end.

    So it would need a bigger change. But then that's what fir is doing.
    (He's never going to get there, but there's no harm in humouring him.)


    what you consider problems is so siple i dont even think on it


    as to ifs syntax i am yet not sure

    some like this may be considered but its not much good loking
    though is sorta logical

    x<10 ? x++>5
    ˙˙˙˙˙˙˙ ?˙ more_than_five
    ˙˙˙˙˙˙˙ ? less_than_six
    ˙˙˙˙ ? do_nothing

    Try: if 5 < x < 10.


    why? its the same


    5<x<10 ?

    interesting problem is if

    a?b?c?d? all must be tru to go here


    so how to implement or this way


    a?b?c?d? {all must be false to go here}
    {or would be here it seems but you may go here also after false
    and it has no end/delimiter so it needs something..}



    so maybe or is

    (a?b?c?d?)? { or is here? }










    --- 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 13 17:17:14 2026
    bart pisze:
    On 13/09/2026 14:21, fir wrote:
    bart pisze:
    On 13/09/2026 11:53, Ike Naar wrote:
    On 2026-09-12, bart <bc@freeuk.com> wrote:
    Note that the code will still have braces. I suggest a better aim
    is to
    eliminate most braces. The should be no need to ever see '} else {'
    instead of just 'else'.

    There can be a difference; for example (assume <stdio.h> included):

    ˙˙˙˙ if (0) { if (1) puts("foo");˙˙ else˙˙ puts("bar"); }

    ˙˙˙˙ if (0) { if (1) puts("foo"); } else { puts("bar"); }

    The first line will print nothing; the second one will print "bar".


    This illustrates my point; first some Pascal:

    ˙˙ if cond then begin s1; s2 end else begin s3; s4 end

    C is the same but uses braces, and semicolons are terminators:

    ˙˙ if (cond) { s1; s2; } else { s3; s4; }

    One has 'end else begin', the other has '} else {'.

    However the Pascal version can be improved; since 'then' and 'else'
    can act as block delimiters:

    ˙˙ if cond then s1; s2 end else s3; s4 end

    Only the final block in a chain (eg. if-else-if) needs the 'end'
    terminator. And now 'else' is by itself.

    Unfortunately this doesn't transfer well to C:

    ˙˙ if (cond) s1; s2; else s3; s4; }

    The () around 'cond' are needed as the ')' separates cond and s1 (fir
    doesn't not appreciate this point; he thinks it is fine for
    statements and expressions to run together provided that there is a
    way to infer where one logically ends and the other starts).

    The trouble is that lone, unbalanced } at the end.

    So it would need a bigger change. But then that's what fir is doing.
    (He's never going to get there, but there's no harm in humouring him.)


    what you consider problems is so siple i dont even think on it


    as to ifs syntax i am yet not sure

    some like this may be considered but its not much good loking
    though is sorta logical

    x<10 ? x++>5
    ˙˙˙˙˙˙˙ ?˙ more_than_five
    ˙˙˙˙˙˙˙ ? less_than_six
    ˙˙˙˙ ? do_nothing

    Try: if 5 < x < 10.

    not btw that if you want make much more rigid and more descriptive
    language youre obviously fukll right to implement this philosophy im not denying this

    i waguely remember i sad to you something like "try" or "you my try"
    giving some of my outcomes as to my philosophy as i assumed you
    want to use something good ;c

    im joking (imo ofc my philosophy here is better but you may use your own
    ofc)

    for me your conventions are suboptimal (all those ones who not by chance
    are mine own ;c )


    --- 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 13 17:23:33 2026
    fir pisze:
    bart pisze:
    On 13/09/2026 14:21, fir wrote:
    bart pisze:
    On 13/09/2026 11:53, Ike Naar wrote:
    On 2026-09-12, bart <bc@freeuk.com> wrote:
    Note that the code will still have braces. I suggest a better aim >>>>>> is to
    eliminate most braces. The should be no need to ever see '} else {' >>>>>> instead of just 'else'.

    There can be a difference; for example (assume <stdio.h> included):

    ˙˙˙˙ if (0) { if (1) puts("foo");˙˙ else˙˙ puts("bar"); }

    ˙˙˙˙ if (0) { if (1) puts("foo"); } else { puts("bar"); }

    The first line will print nothing; the second one will print "bar".


    This illustrates my point; first some Pascal:

    ˙˙ if cond then begin s1; s2 end else begin s3; s4 end

    C is the same but uses braces, and semicolons are terminators:

    ˙˙ if (cond) { s1; s2; } else { s3; s4; }

    One has 'end else begin', the other has '} else {'.

    However the Pascal version can be improved; since 'then' and 'else'
    can act as block delimiters:

    ˙˙ if cond then s1; s2 end else s3; s4 end

    Only the final block in a chain (eg. if-else-if) needs the 'end'
    terminator. And now 'else' is by itself.

    Unfortunately this doesn't transfer well to C:

    ˙˙ if (cond) s1; s2; else s3; s4; }

    The () around 'cond' are needed as the ')' separates cond and s1
    (fir doesn't not appreciate this point; he thinks it is fine for
    statements and expressions to run together provided that there is a
    way to infer where one logically ends and the other starts).

    The trouble is that lone, unbalanced } at the end.

    So it would need a bigger change. But then that's what fir is doing.
    (He's never going to get there, but there's no harm in humouring him.)


    what you consider problems is so siple i dont even think on it


    as to ifs syntax i am yet not sure

    some like this may be considered but its not much good loking
    though is sorta logical

    x<10 ? x++>5
    ˙˙˙˙˙˙˙ ?˙ more_than_five
    ˙˙˙˙˙˙˙ ? less_than_six
    ˙˙˙˙ ? do_nothing

    Try: if 5 < x < 10.

    not btw that if you want make much more rigid and more descriptive
    language youre obviously fukll right to implement this philosophy im not denying this

    i waguely remember i sad to you something like "try" or "you my try"
    giving some of my outcomes as to my philosophy as i assumed you
    want to use something good ;c

    im joking (imo ofc my philosophy here is better but you may use your own ofc)

    for me your conventions are suboptimal (all those ones who not by chance
    are mine own ;c )

    for me the ones im searching are optimal at least ofr last 'research
    state' though i got different worry (on whch i was saint more than one)

    c indeed is on some very impressive track to me and im not quite sure
    using my filosophy (which is at seen very fractal and syntax
    minimalising) is in fact worse than this oryginal "railroad" track

    in old c i by chance see something like 'coal' and 'rails'/railroad
    feeling and in this mine i see its more like light and plastic 'style'
    not so much nice eventually - it worries my but dont know what to do
    with that..maybe its too much far form assembly/machine language but
    today hard to work in machne language on raw steel and oil machines..

    --- 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 13 17:27:08 2026
    fir pisze:
    fir pisze:
    bart pisze:
    On 13/09/2026 14:21, fir wrote:
    bart pisze:
    On 13/09/2026 11:53, Ike Naar wrote:
    On 2026-09-12, bart <bc@freeuk.com> wrote:
    Note that the code will still have braces. I suggest a better aim >>>>>>> is to
    eliminate most braces. The should be no need to ever see '} else {' >>>>>>> instead of just 'else'.

    There can be a difference; for example (assume <stdio.h> included): >>>>>>
    ˙˙˙˙ if (0) { if (1) puts("foo");˙˙ else˙˙ puts("bar"); }

    ˙˙˙˙ if (0) { if (1) puts("foo"); } else { puts("bar"); }

    The first line will print nothing; the second one will print "bar". >>>>>

    This illustrates my point; first some Pascal:

    ˙˙ if cond then begin s1; s2 end else begin s3; s4 end

    C is the same but uses braces, and semicolons are terminators:

    ˙˙ if (cond) { s1; s2; } else { s3; s4; }

    One has 'end else begin', the other has '} else {'.

    However the Pascal version can be improved; since 'then' and 'else' >>>>> can act as block delimiters:

    ˙˙ if cond then s1; s2 end else s3; s4 end

    Only the final block in a chain (eg. if-else-if) needs the 'end'
    terminator. And now 'else' is by itself.

    Unfortunately this doesn't transfer well to C:

    ˙˙ if (cond) s1; s2; else s3; s4; }

    The () around 'cond' are needed as the ')' separates cond and s1
    (fir doesn't not appreciate this point; he thinks it is fine for
    statements and expressions to run together provided that there is a >>>>> way to infer where one logically ends and the other starts).

    The trouble is that lone, unbalanced } at the end.

    So it would need a bigger change. But then that's what fir is
    doing. (He's never going to get there, but there's no harm in
    humouring him.)


    what you consider problems is so siple i dont even think on it


    as to ifs syntax i am yet not sure

    some like this may be considered but its not much good loking
    though is sorta logical

    x<10 ? x++>5
    ˙˙˙˙˙˙˙ ?˙ more_than_five
    ˙˙˙˙˙˙˙ ? less_than_six
    ˙˙˙˙ ? do_nothing

    Try: if 5 < x < 10.

    not btw that if you want make much more rigid and more descriptive
    language youre obviously fukll right to implement this philosophy im
    not denying this

    i waguely remember i sad to you something like "try" or "you my try"
    giving some of my outcomes as to my philosophy as i assumed you
    want to use something good ;c

    im joking (imo ofc my philosophy here is better but you may use your
    own ofc)

    for me your conventions are suboptimal (all those ones who not by
    chance are mine own ;c )

    for me the ones im searching are optimal at least ofr last 'research
    state' though i got different worry (on whch i was saint more than one)

    c indeed is on some very impressive track to me and im not quite sure
    using my filosophy (which is at seen very fractal and syntax
    minimalising) is in fact worse than this oryginal "railroad" track

    in old c i by chance see something like 'coal' and 'rails'/railroad
    feeling and in this mine i see its more like light and plastic 'style'
    not so much nice eventually - it worries my but dont know what to do
    with that..maybe its too much far form assembly/machine language but
    today hard to work in machne language on raw steel and oil machines..

    so i also not judge your language stylistically - it may heve some
    feeling (though i not get this feeling as i dont know it... this feeling
    is maybe a part of times where things were used..as c had probably a
    feeling of thi 60ties or 70ties in MIT (berkeley?) or something

    for ma c has always good 'dark' feeling but all that times was more like
    rain night and oxygene feeling that present times... bright lcd plastic monitors and things

    --- 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 13 18:01:00 2026
    On 13/09/2026 15:34, fir wrote:
    bart pisze:
    On 13/09/2026 14:21, fir wrote:
    bart pisze:
    On 13/09/2026 11:53, Ike Naar wrote:
    On 2026-09-12, bart <bc@freeuk.com> wrote:
    Note that the code will still have braces. I suggest a better aim >>>>>> is to
    eliminate most braces. The should be no need to ever see '} else {' >>>>>> instead of just 'else'.

    There can be a difference; for example (assume <stdio.h> included):

    ˙˙˙˙ if (0) { if (1) puts("foo");˙˙ else˙˙ puts("bar"); }

    ˙˙˙˙ if (0) { if (1) puts("foo"); } else { puts("bar"); }

    The first line will print nothing; the second one will print "bar".


    This illustrates my point; first some Pascal:

    ˙˙ if cond then begin s1; s2 end else begin s3; s4 end

    C is the same but uses braces, and semicolons are terminators:

    ˙˙ if (cond) { s1; s2; } else { s3; s4; }

    One has 'end else begin', the other has '} else {'.

    However the Pascal version can be improved; since 'then' and 'else'
    can act as block delimiters:

    ˙˙ if cond then s1; s2 end else s3; s4 end

    Only the final block in a chain (eg. if-else-if) needs the 'end'
    terminator. And now 'else' is by itself.

    Unfortunately this doesn't transfer well to C:

    ˙˙ if (cond) s1; s2; else s3; s4; }

    The () around 'cond' are needed as the ')' separates cond and s1
    (fir doesn't not appreciate this point; he thinks it is fine for
    statements and expressions to run together provided that there is a
    way to infer where one logically ends and the other starts).

    The trouble is that lone, unbalanced } at the end.

    So it would need a bigger change. But then that's what fir is doing.
    (He's never going to get there, but there's no harm in humouring him.)


    what you consider problems is so siple i dont even think on it


    as to ifs syntax i am yet not sure

    some like this may be considered but its not much good loking
    though is sorta logical

    x<10 ? x++>5
    ˙˙˙˙˙˙˙ ?˙ more_than_five
    ˙˙˙˙˙˙˙ ? less_than_six
    ˙˙˙˙ ? do_nothing

    Try: if 5 < x < 10.


    why? its the same


    The same as ... what?

    I don't know what your example was meant to do. But if testing whether x
    was in some interval, and with my example 'x' is only written once.

    Otherwise you might want to look at how lots of languages do more
    general pattern-matching.>
    5<x<10 ?





    --- 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 Sun Sep 13 18:55:56 2026
    bart <bc@freeuk.com> wrote:
    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.

    Apparenty you ignored first part above. So, let me expand this.
    I see value in specifying interfaces. For me it is important
    design information. It takes some time to get it right. Not
    time to code or type. It takes time to find good design.
    Writing declarations is small part of it. In my use typical import
    statement imports several declarations so is even smaller issue.
    I mentioned non-C project where I have about 1200 modules. There
    are 1115 import statements. Note that some uses imply/are equivalent
    to import, for example there is inheritance of interfaces (given
    interface exports everything that its parents export plus usually some additional things), there is probably about 5 thousends of instances
    of inheritance. Alternatives would involve duplicating some thousends
    of declarations (probably around 10-15 thousends). The system
    has about 150000 LOC (215000 wc lines). Compared to total import
    statements and inheritance specifications are small part. And they
    are relatively trivial: cases where code compiled but import or
    inheritance statements were wrong wre quite rare and they mainly
    were cases of missing export or not needed import. Later re-design
    may change interfaces, but I mean correctness with respect to design
    at time where code was compiled. OTOH normal executable code may
    compile fine but behaves completely wrong, so requires more work,

    I do not think that C can do what this system is doing. But extrapolating, design in C of similar spirt would probably need say 5000 #include
    lines, some hairy macros and 200000-300000 LOC. And executable part
    would be much more tricky to get right.

    To put this in a bit different way, I probably can enter 1000 lines
    daily. If there is enough regularities than I can use tools like cut-and-paste, global replacement and similar to reduce amount of
    typing and to generate say 2000 lines in a day. But when I need
    to write executable code, than in happy cases _maybe_ I can
    generate 500 lines a day. And usually much less than this.
    In case of C I can cut-and-paste between prototypes and function
    header, so aount of work needed to maintain declaration in
    include file is much smaller than for typical code line. If
    I need to change say type in declaration I do this via global
    search and replace going over all sources, so extra work needed
    is proportional to size of prototypes, which is small percentage
    of total sources. And such changes are essentially design changes,
    so need some thought before I make them.

    So, I think that your problem is mostly psychological: you consider export/import info as unimportant and it is painful to you to do
    work that you consider useless. I consider maintaining export/import
    info as important and can do this with resonable efficiency.

    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!

    If I need 1 or 2 names from a module, then it makes sense to specify
    them explicitely. This is important information if you want to change
    design. I certainly do not want to _always_ specify individual names
    and system that I use do not require this.

    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.

    OK. But I look at total work. Old systems like FORTRAN (when
    it was all caps) made things "easy" by providing default type
    for variables based on first letter. Later systems tended to
    be more strict requireing explicit declarations. Modern
    tendecly is to use type inference, either full as in ML and
    followers, or partial like C or C++ 'auto'. Mismatched
    declarations may cause troubles like crashes or wrong output
    that take work to fix. Compared to that mismatches in explicit
    declarations are trivial to fix. So one adds some extra work
    to write and maintain declarations for benefit of better error
    detection and reduction of total work. Type inference means
    almost no reduction in ability to detect errors and some reduction
    of work in maintaining declarations. At least in case of C and
    C++ type inference optional: you can still give explicit types.
    At least your description of of your module system suggest that
    it is more like FORTRAN than modern type interface. That is
    you hardcode some resonable use case. But if it does not match
    user needs, then either program will not build or there will
    be chance of build errors. Maybe you worked out good rules,
    we do not know. But there is a different aspect: local declarations
    are pretty frequent and can be result of macro expansion. So
    'auto' has measurable impact on ease of coding. '#include'
    lines are much less frequent, so possible saving is much smaller.
    Given small possible gain old principle "do not fix what is not
    broken" applies. As I wrote, there are things that should
    be improved and many languages other than C have their own
    module system. But requrement for explicit imports is very
    common.

    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.

    If they want, they can write what they think about this issue.
    Here I am stating my opinion in context of what you wrote.
    One problem with C headers is that a single macro can choose
    a differenet branch in a header, so you either need some sophisticated
    system of dealing with conditionals or you need to re-parse
    whenever any macro is defined differently than during previous
    parse. Also, when we have system that works but burns more CPU
    cycles than desirable, then throwing enough CPU power may be
    best practical solution. That does not stop me for looking for
    more CPU-efficient solutions.

    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.

    Yes, C includes are not real module system, so one needs extra
    conventions.

    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.

    Yes.

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

    In system that I use it is the programmer. System checks that
    declaration match. In case of systems allowing overloading
    there is possiblity that interface file contains one declaration,
    while module body declares different function of the same name.
    That alone is legal. But if function declared in interface has
    no corresponding implementation, then sooner or later this will
    be detected. One possibilty is that compilation of module may
    signal error due to unimplemented export. Another posibility is
    that attempt to use such unimplemented function will cause
    runtime error. The second may be nicer during developement,
    when interface is defined first and implemented in incremental
    way, as it allows testing what is implemented. The first one
    is better when you wnat to compile final program.

    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 I resolve with what you would call "whole program compilation".
    First pass tries to recognize types. Second pass collects info
    about exported functions. I use this in context of explicit interface
    parts, but in fact compiler parses everthing and extracts some
    information from implementation part. So in principle I could
    extract interace based on some markers. After the second pass there
    is normal compilation where imports use info colleded in the second
    pass. This in not particularly fast, for 150000 LOC I need 3.5s
    to extract the interface info. Still, it is small part of the
    whole compilation which needs about 300s CPU time (about 38s
    real time when using 20 cores). Note: those 3.5s by necessity is
    using single core, so I care more about it than about other part
    that can be speeded up by using more cores.

    For languages without overloading one could use multipass approach:
    in first pass collect info about identifiers exported from given
    module and list of modules that it imports. In the second pass
    compiler would found out which module is responsible for defining
    each imported identifier. After that one can do compilation as
    in case of explicit interfaces. That is compiler can find out
    modules which define each identifier needed by the interface.
    If there is cycle between interfaces, that can be detected and
    reported (it is an error in typical implementation of explicit
    interfaces). Otherwise compiler could find an order such that
    each interface depend only on interfaces compiled earlier. After
    that one can compile implementations in any order.

    IIUC Oberon still _allows_ explicit interface files. So one
    could use explicit interfaces to break cycles. That is compiler
    would first compile interface part of A, after that modules using A,
    and finally implementation part of A.

    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.

    Well, I want well specified interfaces between parts of the program.
    With this it is much easier to decide which module is wrong (does not
    comply with its interface) and consequently to fix bugs. Also
    I have modules which can use use one of several other modules.
    That is module M can use function from A, B, C, ... and it should
    work correctly which each one. As long as A, B, C, ... have the
    same interface I can test that M works with say A and the A, B, C, ...
    in fact implement the same interface and after that expect that
    M will also work with B or C. Without well specified interfaces
    that would be much harder (or impossible).

    In different context, one may have collection of modules such that
    some subsets form programs. That is particularly relevant for microcontrollers, where target is too small to include all available
    modules. Also, different microcontrollers may need different
    (alternative) hardware specific modules. In such situation you
    do not want to leak hardware specific details to general modules.
    And in general, you want to limit what is pulled in only to stuff
    that is actually needed.

    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.



    --
    Waldek Hebisch

    --- 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 13 21:14:36 2026
    bart pisze:
    On 13/09/2026 15:34, fir wrote:
    bart pisze:
    On 13/09/2026 14:21, fir wrote:
    bart pisze:
    On 13/09/2026 11:53, Ike Naar wrote:
    On 2026-09-12, bart <bc@freeuk.com> wrote:
    Note that the code will still have braces. I suggest a better aim >>>>>>> is to
    eliminate most braces. The should be no need to ever see '} else {' >>>>>>> instead of just 'else'.

    There can be a difference; for example (assume <stdio.h> included): >>>>>>
    ˙˙˙˙ if (0) { if (1) puts("foo");˙˙ else˙˙ puts("bar"); }

    ˙˙˙˙ if (0) { if (1) puts("foo"); } else { puts("bar"); }

    The first line will print nothing; the second one will print "bar". >>>>>

    This illustrates my point; first some Pascal:

    ˙˙ if cond then begin s1; s2 end else begin s3; s4 end

    C is the same but uses braces, and semicolons are terminators:

    ˙˙ if (cond) { s1; s2; } else { s3; s4; }

    One has 'end else begin', the other has '} else {'.

    However the Pascal version can be improved; since 'then' and 'else' >>>>> can act as block delimiters:

    ˙˙ if cond then s1; s2 end else s3; s4 end

    Only the final block in a chain (eg. if-else-if) needs the 'end'
    terminator. And now 'else' is by itself.

    Unfortunately this doesn't transfer well to C:

    ˙˙ if (cond) s1; s2; else s3; s4; }

    The () around 'cond' are needed as the ')' separates cond and s1
    (fir doesn't not appreciate this point; he thinks it is fine for
    statements and expressions to run together provided that there is a >>>>> way to infer where one logically ends and the other starts).

    The trouble is that lone, unbalanced } at the end.

    So it would need a bigger change. But then that's what fir is
    doing. (He's never going to get there, but there's no harm in
    humouring him.)


    what you consider problems is so siple i dont even think on it


    as to ifs syntax i am yet not sure

    some like this may be considered but its not much good loking
    though is sorta logical

    x<10 ? x++>5
    ˙˙˙˙˙˙˙ ?˙ more_than_five
    ˙˙˙˙˙˙˙ ? less_than_six
    ˙˙˙˙ ? do_nothing

    Try: if 5 < x < 10.


    why? its the same


    The same as ... what?

    I don't know what your example was meant to do. But if testing whether x
    was in some interval, and with my example 'x' is only written once.

    Otherwise you might want to look at how lots of languages do more
    general pattern-matching.>
    5<x<10 ?



    this was not on topic so i dont understand what you mean
    on this comparsions 0<=x<640 i was writing already long ago
    this example was not on checking x but on if-else forms


    --- 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 Sun Sep 13 14:00:10 2026
    On 9/13/2026 4:29 AM, Lane W wrote:
    bart wrote:
    On 13/09/2026 10:53, fir wrote:
    fir pisze:
    bart pisze:

    It sounds like your ideal language would be APL, if is not 'clean'
    and 'clear' that you're after, but 'minimal' and 'cryptic'.

    The first version above is the best balance in my view. You /want/
    some mixture of keywords and symbols.

    In any case, in a typical program, only 1/3 of alphanumerics of
    keywords; the rest will still be user-identifiers.


    i gave you example - its only cryptic if you dont know what it means


    consider for example french or polish language its totally cryptic
    until you will learn it...


    That is not your aim. That appears to be to start with a language that
    you know perfectly well, but remove all punctuation, capitalisation
    and structure, and half the words. But to what purpose; because you're
    too lazy to type?

    ˙˙not to say you want to understand it without
    definitions

    So an APL (or J or K) program is never cryptic because all you have to
    do is learn it? If only I'd thought of that!

    The same applies to Assembly I guess. And machine code?


    overally this discussin ended i think at least as for few months,
    cant continue becouse you repeat the same things

    And you keep repeating the same nonsense. What is your endpoint: a
    program that can be expressed in one byte?

    He wants to compress the language, metaphor a plum, into a prune that
    has much reduced.

    Take a source file, compress it, and show all the printable chars from
    the blob? ;^)



    It is the same way with a newsgroup when the warlord Lane W has
    compressed all the shitheads, David Brown, Keith, bart, and the rest
    except I guess the fellows who are in the mood, when they all conspire
    by email to not respond to anything he writes. It is at such a time that
    he declares victory. As I roll over yet another group in the 97 I have subjugated to my rule and made complacent, a tear drips from my eye. C,
    such a beautiful language, yet what hypocrites such as David Brown
    defending it. Really, nothing personal? I beg to differ. Under my boot,
    a serpent crawls out of the skull of another victim.


    --- 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 Sun Sep 13 17:06:01 2026
    Ike Naar <ike@sdf.org> writes:
    On 2026-09-12, bart <bc@freeuk.com> wrote:
    Note that the code will still have braces. I suggest a better aim is to
    eliminate most braces. The should be no need to ever see '} else {'
    instead of just 'else'.

    There can be a difference; for example (assume <stdio.h> included):

    if (0) { if (1) puts("foo"); else puts("bar"); }

    if (0) { if (1) puts("foo"); } else { puts("bar"); }

    The first line will print nothing; the second one will print "bar".

    I believe bart was suggesting a language change, not offering advice
    on how to program in C.

    In C, the syntax for an "if" statement is:

    if ( expression ) statement
    if ( expression ) statement else statement

    (C23 tweaks this very slightly in ways that are not relevant to
    the current discussion.) Since it's defined in terms of single
    statements, if you want multiple statements in a branch you need to
    create one by enclosing multiple statements in braces. This also
    requires a rule about which "if" a given "else" is associated with.

    Many other langauges allow multiple statements where C only allows
    a single statement. They typically do so by requiring a closing
    delimiter matching the "if", for example "endif", "end if", "end",
    or "fi". They also typically add a single token combining "else"
    and "if", typically "elseif", "elsif", or "elif".

    (Pascal follows the C approach, but spells "{" and "}" as "begin"
    and "end".)

    It's not practical to follow bart's advice (always use "else" rather
    than "} else {" unless you're using some language other than C.

    bart's point, I think, is that he dislikes the way C does this.

    Personally, I tend to prefer the non-C delimited approach, since
    it's a bit less error-prone, but both approaches are perfectly
    valid and can be used cleanly and correctly with a little care.
    It's not a factor I consider when deciding which language to use.

    --
    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 bart@3:633/10 to All on Mon Sep 14 01:44:11 2026
    On 13/09/2026 19:55, Waldek Hebisch wrote:
    bart <bc@freeuk.com> wrote:
    On 09/09/2026 02:59, Waldek Hebisch wrote:

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

    Apparenty you ignored first part above. So, let me expand this.
    I see value in specifying interfaces. For me it is important
    design information. It takes some time to get it right. Not
    time to code or type. It takes time to find good design.
    Writing declarations is small part of it.

    Sure. But interfaces to what? To some sort of library?

    And it isn't really much to do with modules. C libraries have
    interfaces, usually as headers, but it doesn't have modules.

    A more typical problem is organising the functions, variables, types,
    enums and tables of an application into multiple modules: what goes
    where; what needs to be shared.

    Once you have your N modules, then that's the list the language's module scheme uses to build your app.

    A formal interface would be used for external libraries, or for internal libraries where a group of modules form a private sub-program.


    In my use typical import
    statement imports several declarations so is even smaller issue.
    I mentioned non-C project where I have about 1200 modules. There
    are 1115 import statements. Note that some uses imply/are equivalent
    to import, for example there is inheritance of interfaces (given
    interface exports everything that its parents export plus usually some additional things), there is probably about 5 thousends of instances
    of inheritance. Alternatives would involve duplicating some thousends
    of declarations (probably around 10-15 thousends). The system
    has about 150000 LOC (215000 wc lines).

    If you have 215Kloc and 1200 modules, then you have other challenges
    than a module scheme. (That's some 0.18Kloc/module on average, while my
    stuff might be more like 1Kloc, and used to be nearer 2Kloc.)

    But I'm surprised you only have about one import statement per file: is
    it the same project-wide interface file, or is each much more specific?

    Compared to total import
    statements and inheritance specifications are small part. And they
    are relatively trivial: cases where code compiled but import or
    inheritance statements were wrong wre quite rare and they mainly
    were cases of missing export or not needed import. Later re-design
    may change interfaces, but I mean correctness with respect to design
    at time where code was compiled. OTOH normal executable code may
    compile fine but behaves completely wrong, so requires more work,

    I do not think that C can do what this system is doing. But extrapolating, design in C of similar spirt would probably need say 5000 #include
    lines, some hairy macros and 200000-300000 LOC. And executable part
    would be much more tricky to get right.

    I'm now curious as to what weird things you're doing. Is this other language/scheme one like C++, or something that you have devised?

    So, I think that your problem is mostly psychological: you consider export/import info as unimportant and it is painful to you to do
    work that you consider useless. I consider maintaining export/import
    info as important and can do this with resonable efficiency.

    As I suggested above, perhaps 'import/export' are too-strong terms for
    talking about sharing between friendly modules of the same subprogram.

    (A 'subprogram' is my language is one building block down from
    'program', which equates to a single EXE or DLL binary. 'Module' is just
    below that and that corresponds to one source file.)

    Meanwhile interfaces between programs (ie. between EXE/DLL files) is
    something that doesn't come up often for me; it is a different subject,
    and something I would also apply automatic methods to as much as
    possible. It is FFI more than modules.


    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!

    If I need 1 or 2 names from a module, then it makes sense to specify
    them explicitely.

    I don't see why. Unless you mean it is more important to exclude the
    names you haven't listed?

    Support a library or module M exports functions A - F. You'd write:

    import M

    then later you can write M.A() to M.F() without doing anything else.

    Suppose you only need function D. In that case you just call M.D();
    nothing is forcing you to call M.E() too!

    If this is about not having to include those functions in the binary,
    then that would be something for the language to deal with: it knows
    which functions have called, and knows those are the ones to import.




    Mismatched
    declarations may cause troubles like crashes or wrong output
    that take work to fix. Compared to that mismatches in explicit
    declarations are trivial to fix. So one adds some extra work
    to write and maintain declarations for benefit of better error
    detection and reduction of total work.

    What benefits are these? All I can see are loads of annoying errors
    because you've forgotten to declare entities.


    Type inference means
    almost no reduction in ability to detect errors and some reduction
    of work in maintaining declarations. At least in case of C and
    C++ type inference optional: you can still give explicit types.
    At least your description of of your module system suggest that
    it is more like FORTRAN than modern type interface.

    Type inference and modules are different things. Modules manage
    visibility named entities including types across source files.

    With my whole-program scheme, there will never be type mismatches across
    the sources files of a particular program. That can only happen when interface/API info and implementation or binary are separate.

    (Type inference is minimal, nothing like H-M. In any case my Modules
    work the same way across two languages, one fully typed and static, the
    other dynamically typed.)


    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.

    If they want, they can write what they think about this issue.

    They're users who are proficient in their tools. Nothing ever seem to be
    a problem - that superfast hardware and dozens of parallel cores can't
    fix! I've learnt from experience that even a build time of minutes
    (where the result might be a mere 1MB binary) doesn't faze them.

    Oh, it's a 'one-off', or they are not curious as to why a simple task
    isn't faster.

    Basically they are not interested in any merits of my solutions.

    Here I am stating my opinion in context of what you wrote.
    One problem with C headers is that a single macro can choose
    a differenet branch in a header, so you either need some sophisticated
    system of dealing with conditionals or you need to re-parse
    whenever any macro is defined differently than during previous

    All the problems with C headers would be a big subject by itself!

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

    In system that I use it is the programmer. System checks that
    declaration match.

    C uses the 'linkage' system for functions and variables. It uses text replication to share entities such as types, structs, enumerations and
    macros. How do other language's modules cope with the latter?

    (I only know about Python. My languages of course handle all those too.)


    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 I resolve with what you would call "whole program compilation".
    First pass tries to recognize types. Second pass collects info
    about exported functions. I use this in context of explicit interface
    parts, but in fact compiler parses everthing and extracts some
    information from implementation part. So in principle I could
    extract interace based on some markers. After the second pass there
    is normal compilation where imports use info colleded in the second
    pass. This in not particularly fast, for 150000 LOC I need 3.5s
    to extract the interface info. Still, it is small part of the
    whole compilation which needs about 300s CPU time (about 38s
    real time when using 20 cores).

    This is that 215Kloc project? 300s (approx time for single core) is
    pretty slow for that. What is the problem here; the language being hard
    to process?

    (As you know my stuff works perhaps 3 magnitudes faster, assuming your
    machine is faster.

    Although I am currently investigating why my C compiler takes 0.12
    seconds to process some 0.5M lines of SDL3 headers when TCC takes only
    0.05 seconds. I'm just curious.

    An odd fact I discovered today: if SDL3 headers (86 files/82Kloc) are preprocessed, the result is only 4000 lines and 27K tokens, even though
    550K lines are processed according to my compiler (but maybe that's why
    it's slow).

    This output is not enough to use as a new compact header; it will need #defines etc that have been stripped. But it shows the core of the API
    is quite small. I will investigate further.)


    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.

    Well, I want well specified interfaces between parts of the program.
    With this it is much easier to decide which module is wrong (does not
    comply with its interface) and consequently to fix bugs.

    As I said, many of my modules are friendly. I don't care about formal interfaces. When I do, a module or several can form their own more
    private group.

    This makes coding much, much simpler.

    Also
    I have modules which can use use one of several other modules.
    That is module M can use function from A, B, C, ... and it should
    work correctly which each one. As long as A, B, C, ... have the
    same interface I can test that M works with say A and the A, B, C, ...
    in fact implement the same interface and after that expect that
    M will also work with B or C. Without well specified interfaces
    that would be much harder (or impossible).

    When happens when A gets too big and you want to split it into A1 and
    A2; will it need a new formal interface between them?


    In different context, one may have collection of modules such that
    some subsets form programs. That is particularly relevant for microcontrollers, where target is too small to include all available
    modules. Also, different microcontrollers may need different
    (alternative) hardware specific modules. In such situation you
    do not want to leak hardware specific details to general modules.
    And in general, you want to limit what is pulled in only to stuff
    that is actually needed.

    I work with a 64-bit supercomputer with huge amounts of memory. (In
    other words, the second-cheapest PC in the shop.)

    Still, last year I adapted my systems language to work with an emulated
    Z80 system, and the module scheme still worked!

    Yes, the memory is more limited, you just have less stuff in the
    modules. The scheme allows for some flexibility.


    --- 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 Mon Sep 14 07:41:03 2026
    bart <bc@freeuk.com> wrote:
    On 13/09/2026 19:55, Waldek Hebisch wrote:
    bart <bc@freeuk.com> wrote:
    On 09/09/2026 02:59, Waldek Hebisch wrote:

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

    Apparenty you ignored first part above. So, let me expand this.
    I see value in specifying interfaces. For me it is important
    design information. It takes some time to get it right. Not
    time to code or type. It takes time to find good design.
    Writing declarations is small part of it.

    Sure. But interfaces to what? To some sort of library?

    And it isn't really much to do with modules. C libraries have
    interfaces, usually as headers, but it doesn't have modules.

    If you want popular comparisons look at Modula 2 or Turbo Pascal.
    Each module has interface part and implementation part. Form
    outside you can only see what is in the interface part. In
    particular to compile any module using A you only need interface
    part of A. You can compile implementation of A later, or even
    change implementataion of A _after_ you compiled users.

    A more typical problem is organising the functions, variables, types,
    enums and tables of an application into multiple modules: what goes
    where; what needs to be shared.

    You may view interface as information about what needs to be shared,
    but IMO there is more to this. In badly designed program a lot
    must be shared. In well designed program and assuming that problem
    domain is suitable for modularization sharing is quite limited.
    And frequently is is possible to replace implementation part by
    quite a different thing without affectiong correctness of the
    program.

    To make a concrete example, I needed simple varianat of regular
    expressions. In principle I could call existing library via FFI, but
    that had its own problems. Since the core algorithm is quite simple
    I decided to roll my own. I ended with collection of 4 modules.
    One module implements a single node of automation, second one
    implements matching algorithm and build automation (that is graph
    of nodes) from other data. Third module provides a higher level
    abstractions, representing patterns build from simpler automatons
    via boolean operations. Fourth module contains a parser which
    converts textual patterns to internal representation, using
    operations provided by earlier modules. Together this is 452
    wc lines. One may be tempted to do this a single module, but
    I think that what I did have better structure: first module
    essentially defines data struture (or maybe I should say data
    type) and in principle this could be part of the second module.
    But having module means that some things are hidden and some
    are exported in nicer form. So I do not consider having this
    as a separtate module as a big deal, but I think that overall
    thanks to this code is a little nicer. Second module implements
    core algorithm. IMO is is nice that this code is not mixed
    with other parts and also it is potentially reusable in the
    future. Third module implements feature that I needed, it
    is something that AFAIK is not supported by standard libraries
    so I would need it even if I decided to scrap the first two
    modules and replace them by FFI calls to some standard library.
    The actual syntax of supported patterns is confined to the
    fourth module. If I needed different syntax (possibly with
    different featurs set) I can provide an alternative parser
    module. As you later write those are "friendly" modules
    designed to work together. But each of them have reasonably
    well specified responsibilities. And since responsiblity
    of each module is rather narrow, each of them is simple,
    almost trivial. Functionality provided by this collection
    of 4 modules is not very impressive, but less trivial than
    each of the involved modules.

    Once you have your N modules, then that's the list the language's module scheme uses to build your app.

    A formal interface would be used for external libraries, or for internal libraries where a group of modules form a private sub-program.


    In my use typical import
    statement imports several declarations so is even smaller issue.
    I mentioned non-C project where I have about 1200 modules. There
    are 1115 import statements. Note that some uses imply/are equivalent
    to import, for example there is inheritance of interfaces (given
    interface exports everything that its parents export plus usually some
    additional things), there is probably about 5 thousends of instances
    of inheritance. Alternatives would involve duplicating some thousends
    of declarations (probably around 10-15 thousends). The system
    has about 150000 LOC (215000 wc lines).

    If you have 215Kloc and 1200 modules, then you have other challenges
    than a module scheme. (That's some 0.18Kloc/module on average, while my stuff might be more like 1Kloc, and used to be nearer 2Kloc.)

    Actually, having a lot of small modules makes things easy. I have
    a few larger modules (one is about 3.5K wc lines and it is possible
    that some are larger than that), that are harder. Actually, the
    problem are interactions in bigger modules. If I could neatly
    separate parts of big module I would probably split it.

    But I'm surprised you only have about one import statement per file: is
    it the same project-wide interface file, or is each much more specific?

    As I wrote, there is inheritance which is used much more frequently
    than import. And import means that all functions from imported
    module may be used without qualification. That is if module A
    exports function f, than after importing A I can just write 'f()'
    to call 'f' (assuming it needs no arguments). In any place (without
    need for import statement) I can use qualified name, that is
    write 'f()$A' to call 'f' from module 'A'. There are about 8000
    of such qualified calls.

    Also, about 160 modules are purely interface, it makes no sense to
    import them and they do not import anything. They are only used
    with inheritance. About 90 are mostly interface, they provide
    functions accesible via inheritance and normally are not imported.
    about 400 modules work as abstract data types, that is they provide
    functions to create and access various data structures.

    Compared to total import
    statements and inheritance specifications are small part. And they
    are relatively trivial: cases where code compiled but import or
    inheritance statements were wrong wre quite rare and they mainly
    were cases of missing export or not needed import. Later re-design
    may change interfaces, but I mean correctness with respect to design
    at time where code was compiled. OTOH normal executable code may
    compile fine but behaves completely wrong, so requires more work,

    I do not think that C can do what this system is doing. But extrapolating, >> design in C of similar spirt would probably need say 5000 #include
    lines, some hairy macros and 200000-300000 LOC. And executable part
    would be much more tricky to get right.

    I'm now curious as to what weird things you're doing. Is this other language/scheme one like C++, or something that you have devised?

    That scheme shares some similarity to C++, but there are differences.
    One thing is that at least nominaly there is very strong separation
    between modules. Namely data related to a module is invisible
    outside, all you can do is to call functions provided by the module.
    You may guess that if that was completely true at implementation
    level, then performance would be rather poor needing a lot of
    function call. So there is a compromise, performance critical
    functions (like array indexing) are inlined between modules.
    In few rare cases one module uses low level tricks to directly
    access data of other module. But in vast majority of cases the
    isolation is respected. There are performance traps, but with
    care performance can be quite good.

    This scheme was invented by other folks in period between 1975-1985.
    I have added some changes and improvements, but essential features
    are preserved.

    Anyway, there is string type checking and isolation between modules,
    for me it makes developement much easier. There is garbage collection.
    There is code reuse via inheritance and via generic coding (the
    same code can work with different data types). To get similar
    effects in C one would have to either use macros (to generate
    variants of "the same" code for different types) or call functions
    via dispatch tables. That would need extra code and would result
    in weaker type checking. The code intesively uses operator and
    function overloading, it would be more bulky and harder to read
    without that. C++ could do some things that I need, but it seems
    that it also lacks some features and AFAICS in current form could
    not serve as a replacement.

    So, I think that your problem is mostly psychological: you consider
    export/import info as unimportant and it is painful to you to do
    work that you consider useless. I consider maintaining export/import
    info as important and can do this with resonable efficiency.

    As I suggested above, perhaps 'import/export' are too-strong terms for talking about sharing between friendly modules of the same subprogram.

    As I wrote I have very strong isolation between modules, even if
    they are designed to work together. And normally I aim at clearly
    divided responsibilities. So IMO 'import/export' correspond with
    my reality.

    (A 'subprogram' is my language is one building block down from
    'program', which equates to a single EXE or DLL binary. 'Module' is just below that and that corresponds to one source file.)

    Meanwhile interfaces between programs (ie. between EXE/DLL files) is something that doesn't come up often for me; it is a different subject,
    and something I would also apply automatic methods to as much as
    possible. It is FFI more than modules.


    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!

    If I need 1 or 2 names from a module, then it makes sense to specify
    them explicitely.

    I don't see why. Unless you mean it is more important to exclude the
    names you haven't listed?

    Support a library or module M exports functions A - F. You'd write:

    import M

    then later you can write M.A() to M.F() without doing anything else.

    As I wrote I can use equvalent of M.A() without import. And I find
    this preferable when I need only 1 or 2 functions from a module.

    Suppose you only need function D. In that case you just call M.D();
    nothing is forcing you to call M.E() too!

    In my case import means that functions are available without
    qualification, so plain E() may call function from imported module.
    And I have function overloading and partial type inference. In
    effect, it is not entirely trivial to decide which function is
    actually called when you write E(). Most functions either needs
    arguments or produces values (or both), so calling wrong functions
    almost surely is not a big problem, that is either overloading
    machinery would choose the correct one, or call to wrong one will
    result in type error. But still, I think that is better to limit
    possible confusion and import as little as possible.

    If this is about not having to include those functions in the binary,
    then that would be something for the language to deal with: it knows
    which functions have called, and knows those are the ones to import.

    No, that is purely compile time thing, that is controling what
    may be called by limiting visibility.

    Mismatched
    declarations may cause troubles like crashes or wrong output
    that take work to fix. Compared to that mismatches in explicit
    declarations are trivial to fix. So one adds some extra work
    to write and maintain declarations for benefit of better error
    detection and reduction of total work.

    What benefits are these? All I can see are loads of annoying errors
    because you've forgotten to declare entities.

    I remember maybe one or two cases when wrong function was called
    and that passed type checking. Without control of visibility
    such cases would be much more frequent. Note: without overloading
    such cases would normally be detected as mismatched definitions,
    unless somebody adds extra rules that say last import wins.
    But for me overloading and type interface are large benefits
    and comparably need to control visiblity is modest cost.

    More generally, I also worked with dynamic languages where one
    simply calls a function and types of arguments are only checked
    on use. IME code in such languages needs a lot of testing, much
    more than with type checking. That is without type checking
    it is too easy to ship code which calls a function with argument
    of wrong type. Clearly to check types compiler must know them.
    And absent total type reconstrution (like in ML), one needs to
    declare types of arguments and return type of functions.
    So I hope that is part is clear.

    You may doubt necessity of having duplicate declaration in the
    module interface. In principle compiler could do all needed
    checks having only single declaration. But compilers that I
    use need declaration in interface part. And when reading code I
    actually prefer to have both declarations. Namely, when looking
    at interactions between modules I look at interface parts and
    want to see relevant declarations there. When working on inner
    part of module I want relevant info there. For example, I disliked
    standard Pascal rule that forward declaration contained all
    info, but corresponding defintion contained just function name
    skipping arguments types and names. For me extra effort during
    reading, due to extral lookup for missing info meant more work
    compared to cut-and-paste needed to duplicate function header.

    Type inference means
    almost no reduction in ability to detect errors and some reduction
    of work in maintaining declarations. At least in case of C and
    C++ type inference optional: you can still give explicit types.
    At least your description of of your module system suggest that
    it is more like FORTRAN than modern type interface.

    Type inference and modules are different things. Modules manage
    visibility named entities including types across source files.

    Sure. I mentioned type inference to illustrate that approach may
    change and if compiler can infer needed information, then languages
    may depend on this saving programmer work. But gross rules like
    firt letter rule of old FORTRAN (or implicit int from traditional
    C) are unsatisfactory. And when talking about modules your
    rule "all modules are visible" looks more like old gross rules and
    unlike inference process.

    With my whole-program scheme, there will never be type mismatches across
    the sources files of a particular program. That can only happen when interface/API info and implementation or binary are separate.

    AFAICS there is possibilty of calling wrong function (if there are
    2 functions having the same name and argument types). And with
    type inference there is even some possibility of getting wrong
    type: compiler calls function giving wrong result type and then
    passes this type to a different function. Of course, since you
    have function declarations compiler can ensure that passed type is
    appropriate for called function. But that still leaves some
    possiblity of calling wrong function, especially if programmer
    uses only a handful of types and reuses function names.

    (Type inference is minimal, nothing like H-M. In any case my Modules
    work the same way across two languages, one fully typed and static, the other dynamically typed.)


    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.

    If they want, they can write what they think about this issue.

    They're users who are proficient in their tools. Nothing ever seem to be
    a problem - that superfast hardware and dozens of parallel cores can't
    fix! I've learnt from experience that even a build time of minutes
    (where the result might be a mere 1MB binary) doesn't faze them.

    Oh, it's a 'one-off', or they are not curious as to why a simple task
    isn't faster.

    Basically they are not interested in any merits of my solutions.

    Here I am stating my opinion in context of what you wrote.
    One problem with C headers is that a single macro can choose
    a differenet branch in a header, so you either need some sophisticated
    system of dealing with conditionals or you need to re-parse
    whenever any macro is defined differently than during previous

    All the problems with C headers would be a big subject by itself!

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

    In system that I use it is the programmer. System checks that
    declaration match.

    C uses the 'linkage' system for functions and variables. It uses text replication to share entities such as types, structs, enumerations and macros. How do other language's modules cope with the latter?

    Typical approach is to have compiled version of interface. That
    requires some method to write such info to files. IIUC GNU C
    precompiled headers use (or used) crude but simple method: they
    just dumpled memory area containing intenal compiler representation
    of the header. This is simple and fast, but any tiny mismatch could
    lead to error, so this mechanizm has serious limitations and is
    unsuitable for use with modules. GNU Pascal walked internal tree
    of nodes, keeping visted nodes in a hash table to make sure that
    needed node is stored exactly one. During storing each node was
    assigned integer identifier and all pointers were repleaced by
    identifiers (numbers) of taget node. Reading worked in reverse:
    it re-build nodes in memory, replacing numeric indentifiers by
    pointers.

    The system I mentioned above writes interface information in textual
    form, but it is easier to parse and more explicit than source code.

    (I only know about Python. My languages of course handle all those too.)


    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 I resolve with what you would call "whole program compilation".
    First pass tries to recognize types. Second pass collects info
    about exported functions. I use this in context of explicit interface
    parts, but in fact compiler parses everthing and extracts some
    information from implementation part. So in principle I could
    extract interace based on some markers. After the second pass there
    is normal compilation where imports use info colleded in the second
    pass. This in not particularly fast, for 150000 LOC I need 3.5s
    to extract the interface info. Still, it is small part of the
    whole compilation which needs about 300s CPU time (about 38s
    real time when using 20 cores).

    This is that 215Kloc project? 300s (approx time for single core) is
    pretty slow for that. What is the problem here; the language being hard
    to process?

    There are some challenges, that like type inference and function
    overloading. Actually, handling of types is pretty complex.
    Types have parameters and various things, like which functions
    are really exported depends on parameters. So to decide if a
    call is legal compiler may be forced to do rather complex reasoning.
    But AFAICS the main trouble is simple-minded apprach to compilation.
    Namely to allow overloading compiler in sequence tries all visible
    functions with given name. For each possiblity it tries to compile
    argument getting right types. This process is recursive. In
    effect, a subexpression of a complex expression may be compiled
    multiple times (exponentially many in size of the whole expression).
    Usually expressions are resonably small and good possibility is
    found relatively early. But 5 seconds for a single line is
    possible. In addition compiler uses linear search in symbol table.
    This is caused by complexity of maintaining symbol table in other
    forms: during recursive search things get inserted in rather irregular
    way and removal depends on linear structure. Actually, I added
    a hash table that handles most searches, but some searches really
    need linear search and they take most time.

    Getting rid of recursion and implied by this multiple re-compilation
    probably would give 3-5 times faster compilation (and hopefully
    would eliminate really bad cases). If things could be simplified
    so that hash table is enough, that probably would double speed.
    Once that is handled other things would requre attention. But
    it does not make much sense to fight for small speedups in other
    places when biggest issues (that is recursive compilation and
    linear search are unresolved). And that require substantial
    rework. Even after rework compiler is unlikly to be as fast as
    yours. Namely overloading and type inference means to at any
    compilation step there may be multiple possiblities. I do not
    know how many, but 2-3 are likely per average call site and
    in more compilcated expressions this may compound, maybe to
    tens, maybe to thousends. So to find correct types compiler
    will have to do more work than compiler without such a
    feature. As I wrote, I do not know how much, but 3 times
    more work is probably too optimistic, someting between 10 and
    20 is more liekely and really hope that worse cases are rare
    so that they do not affect average too much.

    Also, compiler is using higher level data structures that
    has its own costs. Parsing this 215K wc lines takes 1 second,
    while it should be possible to do this in 0.1 second. But
    again, before other issues are handled relative gain from
    faster parser is too small to bother (I may speed up parser
    if I need to reorganize it to implement some extra feature).

    BTW: It is hard to compare compile speed in longer time because
    machines got faster. But when I started my work build needed
    something like 2.5 hours, so now is way faster. Some speedup
    comes from Makefile-s (skipping useless recompilation). Most
    from faster computers. But factor between 2 and 3 probably is
    due to may work.

    (As you know my stuff works perhaps 3 magnitudes faster, assuming your machine is faster.

    Although I am currently investigating why my C compiler takes 0.12
    seconds to process some 0.5M lines of SDL3 headers when TCC takes only
    0.05 seconds. I'm just curious.

    An odd fact I discovered today: if SDL3 headers (86 files/82Kloc) are preprocessed, the result is only 4000 lines and 27K tokens, even though
    550K lines are processed according to my compiler (but maybe that's why
    it's slow).

    When I need to look at preprocessed files I frequently see a lot of
    blank lines, so I am not surprised that headers get smaller. At first
    glance 4000 lines after preprocessing looks too small, but maybe it
    is real.

    This output is not enough to use as a new compact header; it will need #defines etc that have been stripped. But it shows the core of the API
    is quite small. I will investigate further.)

    At some time I did a little work on Mac OS API. There was about
    220 tousends symbols, of which something like 200 tousends where
    various magic constants. So, maybe bulk od SDL3 headers is due
    to defiend constants?

    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.

    Well, I want well specified interfaces between parts of the program.
    With this it is much easier to decide which module is wrong (does not
    comply with its interface) and consequently to fix bugs.

    As I said, many of my modules are friendly. I don't care about formal interfaces. When I do, a module or several can form their own more
    private group.

    This makes coding much, much simpler.

    It seems that our coding style and methodology differ. I find it
    simpler with specified interfaces. OK, I do varios small or ad
    hoc things and in such case I do not bother much with interfaces.
    But if code is intended to live longer and fit into something
    bigger, then I care much about interfaces. And IMO in longer
    term that is easier.

    Also
    I have modules which can use use one of several other modules.
    That is module M can use function from A, B, C, ... and it should
    work correctly which each one. As long as A, B, C, ... have the
    same interface I can test that M works with say A and the A, B, C, ...
    in fact implement the same interface and after that expect that
    M will also work with B or C. Without well specified interfaces
    that would be much harder (or impossible).

    When happens when A gets too big and you want to split it into A1 and
    A2; will it need a new formal interface between them?

    Yes. Let me add that that I am not too worried by biggish piece
    of code. Say, I would probably keep 20000 lines in a single file
    if I could not find reasonably natural way to split it into pieces.
    OTOH, if there is natural division into parts which are 100 lines
    each, then I probably would split it into such small parts.

    Let me add, that in C if file gets really too big, but there is
    no natural split into modules, then I may accept a multi-file
    module. But this is not an option if a language implementation
    assumes that file=module.

    In different context, one may have collection of modules such that
    some subsets form programs. That is particularly relevant for
    microcontrollers, where target is too small to include all available
    modules. Also, different microcontrollers may need different
    (alternative) hardware specific modules. In such situation you
    do not want to leak hardware specific details to general modules.
    And in general, you want to limit what is pulled in only to stuff
    that is actually needed.

    I work with a 64-bit supercomputer with huge amounts of memory. (In
    other words, the second-cheapest PC in the shop.)

    Me too. But I work with a few architectures: x86_64, aarch64 and
    riscv64. The only realy fast and big is a PC, but the other are
    useful too. Actually, few days ago I worked on code generators
    for a different compiler than discussed above, targeting aarch64
    and riscv64.

    Still, last year I adapted my systems language to work with an emulated
    Z80 system, and the module scheme still worked!

    Yes, the memory is more limited, you just have less stuff in the
    modules. The scheme allows for some flexibility.

    I am not trying to have native compiler for such machines. Rather,
    for microcontrollers I use cross compilers. Certainly, I could have
    some fun trying to create native compiler for such machine, but
    I have enough fun with what I am doing and I am trying to avoid
    starting too many projects that I will not be able to finish due
    to lack of time.

    --
    Waldek Hebisch

    --- 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 14 09:49:21 2026
    bart pisze:

    And it isn't really much to do with modules. C libraries have
    interfaces, usually as headers, but it doesn't have modules.



    out of contex as i not readed most of this branch but obviously C has
    modules

    if you may compile some c files with no resolved 'linkage' to like .o or
    .obj etc they are modules

    if you would need "close up" all linkage and compiel only to exe etc
    that it can be said it has not

    (c has no this new concept im talking about it is if you mix structure
    and function then function vanish structures vanish (stays as edge
    cases) and you only have some 'modules' here - but thats quite other
    story ;C


    --- 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 14 11:27:16 2026
    On 14/09/2026 08:49, fir wrote:
    bart pisze:

    And it isn't really much to do with modules. C libraries have
    interfaces, usually as headers, but it doesn't have modules.



    out of contex as i not readed most of this branch but obviously C has modules

    if you may compile some c files with no resolved 'linkage' to like .o
    or .obj etc they are modules

    No. We might informally use 'modules' to mean individual source files or translation units. A program may comprise multiple translation units. C
    allows independent compilation of such units and there needs to be a
    linking process to combine them.

    This is not the same as a language supporting a proper module scheme. Otherwise even Assembly has modules!

    Without modules, building a program in C looks like this:

    tcc prog.c a.c b.c c.c d.c e.c ...

    With modules, it would be just:

    tcc prog.c

    Both produce prog.exe. This illustrates automatic discovery of the
    source files, but real modules would have other benefits too.



    --- 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 14 14:01:39 2026
    On 14/09/2026 08:41, Waldek Hebisch wrote:
    bart <bc@freeuk.com> wrote:

    A more typical problem is organising the functions, variables, types,
    enums and tables of an application into multiple modules: what goes
    where; what needs to be shared.

    You may view interface as information about what needs to be shared,
    but IMO there is more to this. In badly designed program a lot
    must be shared. In well designed program and assuming that problem
    domain is suitable for modularization sharing is quite limited.
    And frequently is is possible to replace implementation part by
    quite a different thing without affectiong correctness of the
    program.

    To make a concrete example, I needed simple varianat of regular
    expressions. In principle I could call existing library via FFI, but
    that had its own problems. Since the core algorithm is quite simple
    I decided to roll my own. I ended with collection of 4 modules.
    One module implements a single node of automation, second one
    implements matching algorithm and build automation (that is graph
    of nodes) from other data. Third module provides a higher level abstractions, representing patterns build from simpler automatons
    via boolean operations. Fourth module contains a parser which
    converts textual patterns to internal representation, using
    operations provided by earlier modules. Together this is 452
    wc lines. One may be tempted to do this a single module, but
    I think that what I did have better structure: first module
    essentially defines data struture (or maybe I should say data
    type) and in principle this could be part of the second module.
    But having module means that some things are hidden and some
    are exported in nicer form. So I do not consider having this
    as a separtate module as a big deal, but I think that overall
    thanks to this code is a little nicer. Second module implements
    core algorithm. IMO is is nice that this code is not mixed
    with other parts and also it is potentially reusable in the
    future. Third module implements feature that I needed, it
    is something that AFAIK is not supported by standard libraries
    so I would need it even if I decided to scrap the first two
    modules and replace them by FFI calls to some standard library.
    The actual syntax of supported patterns is confined to the
    fourth module. If I needed different syntax (possibly with
    different featurs set) I can provide an alternative parser
    module. As you later write those are "friendly" modules
    designed to work together. But each of them have reasonably
    well specified responsibilities. And since responsiblity
    of each module is rather narrow, each of them is simple,
    almost trivial. Functionality provided by this collection
    of 4 modules is not very impressive, but less trivial than
    each of the involved modules.

    So let's say I implement this as four modules node.m, match.m,
    patterns.m, parser.m.

    Since they are really one unit, then anything that needs to be shared
    between them is marked 'global' to export, but see below.

    How they are imported depends on how they are to be used. They could be casually added to the modules of my application. Then I add these lines
    to its project info:

    module node
    module match
    module patterns
    module parser

    I can access its exported names directly without a qualifier as F(), or
    I can use mode.F(), parser.F() etc depending on where it lives.

    This forms part of my app and will be compiled as part of the
    whole-program build.

    However this is too casual: there is no real connection between it my
    and my own app. I can also see names shared across the four modules
    which are meant to be private (and it can access names in /my/ app!).

    So probably this would be made into its own subprogram. It will need its
    own module info, either added to one designated module, or more usually
    in a dedicated lead module, say called rex.m, which contains those same
    lines:

    module node
    module match
    module patterns
    module parser

    A further change is that those 'global' attributes need to be changed to 'export' to make them visible outside.

    Now, in my app, I add this one line to the project info:

    import rex

    I can now still call F(), or qualify it as rex.F(); I no longer need to
    know where F exists. (However, exported names must be unique; I can't
    use both node.F() and match.F().)

    'rex' and its modules can no longer see my apps global names. Its source
    files however will still be compiled into my app.

    So that's two approaches to such a library that my scheme allows for.
    There is a third one: to put the library into its own DLL.

    The start point is the second approach, with rex.m and the four modules.
    But now I build it as a separate binary like this:

    mm -dll rex # creates rex.dll

    In my app, it now needs separate declarations which look like this:

    importdll rex =
    ... FFI declarations for rex's exports
    end

    This is not project info and can located anywhere. The declarations can
    be created in several ways:

    * Manually, but then they must keep track of any changes in the library

    * If rex was a C library, I can use a tool to do most of the work of
    creating this import block from a C header.

    * If written in my language, then 'mm -dll rex' will also write a
    suitable import module containing that 'importdll' block, either called rex_lib.m or rex.q depending on which of my two languages was
    configured. Then in my app's project info I can write one of:

    module rex_lib # (using rex.m would overwrite the rex.m original)
    module rex

    That exported function can still called as F(), or as rex_lib.F() or
    rex.F().

    I still build my app as 'mm app'; it will automatically pull in rex.dll.

    What it doesn't do at the minute is write docs: collate doc-info from
    the exported module and write into a file to act as documentation.

    I used to have support for such doc-strings but dropped it due to lack
    of use.


    To summarise using this example 4-module library:

    (1) Add 4 'module' directives to my own app

    (2) Put them into rex.m then add 'module rex' to my app

    (3) Put them into rex.m, build as DLL, then add 'module rex/rex_lib'
    to my app

    This last will probably most appeal to you and corresponds most closely
    to your discrete interfaces. However it is more chaotic since it needs a separate set of declarations from from the definitions in the 4 modules.

    (May respond to other points in your post later.)



    --- 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 14 14:09:23 2026
    On 14/09/2026 14:01, bart wrote:

    To summarise using this example 4-module library:

    ˙ (1) Add 4 'module' directives to my own app

    ˙ (2) Put them into rex.m then add 'module rex' to my app

    Sorry, that would be 'import rex' now.


    ˙ (3) Put them into rex.m, build as DLL, then add 'module rex/rex_lib'
    ˙˙˙˙˙ to my app
    And that module contains 'importdll rex`, yet a further level in my
    module scheme.

    There used to be a 4th experimental option which was this:

    importd rex

    This would directly use rex.dll, which needed to have embedded within it (accessed via an exported function or variable) all the declarations and
    other info required to make make use of it.

    However, this would be of most use with other people's DLLs, but
    obviously nobody is going to add such info, even if they could agree the format.

    --- 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 14 16:03:55 2026
    bart pisze:
    On 14/09/2026 08:49, fir wrote:
    bart pisze:

    And it isn't really much to do with modules. C libraries have
    interfaces, usually as headers, but it doesn't have modules.



    out of contex as i not readed most of this branch but obviously C has
    modules

    if you may compile some c files with no resolved 'linkage' to like .o
    or .obj etc they are modules

    No. We might informally use 'modules' to mean individual source files or translation units. A program may comprise multiple translation units. C allows independent compilation of such units and there needs to be a
    linking process to combine them.

    This is not the same as a language supporting a proper module scheme. Otherwise even Assembly has modules!

    Without modules, building a program in C looks like this:

    ˙ tcc prog.c a.c b.c c.c d.c e.c ...

    With modules, it would be just:

    ˙ tcc prog.c

    Both produce prog.exe. This illustrates automatic discovery of the
    source files, but real modules would have other benefits too.


    No, C has modules those compilation units are modules (it that make
    binary modules that you can then link)

    ofc those modules are quite 'thin' or how to call it but for shure those
    are modules.. what you cay with this example is specific functionality
    related to modules but not all need to have it

    (also no need to enlight me on things i was talking quite clearly and
    loudly many years ago (as far as i remember my first post oon this group
    was on related things - i mean the problem that c cupports those modules
    but dont support module names and it may simply make crash or clask of
    symbols

    --- 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 14 16:15:32 2026
    fir pisze:
    bart pisze:
    On 14/09/2026 08:49, fir wrote:
    bart pisze:

    And it isn't really much to do with modules. C libraries have
    interfaces, usually as headers, but it doesn't have modules.



    out of contex as i not readed most of this branch but obviously C has
    modules

    if you may compile some c files with no resolved 'linkage' to like .o
    or .obj etc they are modules

    No. We might informally use 'modules' to mean individual source files
    or translation units. A program may comprise multiple translation
    units. C allows independent compilation of such units and there needs
    to be a linking process to combine them.

    This is not the same as a language supporting a proper module scheme.
    Otherwise even Assembly has modules!

    Without modules, building a program in C looks like this:

    ˙˙ tcc prog.c a.c b.c c.c d.c e.c ...

    With modules, it would be just:

    ˙˙ tcc prog.c

    Both produce prog.exe. This illustrates automatic discovery of the
    source files, but real modules would have other benefits too.


    No, C has modules those compilation units are modules (it that make
    binary modules that you can then link)

    ofc those modules are quite 'thin' or how to call it but for shure those
    are modules.. what you cay with this example is specific functionality related to modules but not all need to have it

    (also no need to enlight me on things i was talking quite clearly and
    loudly many years ago (as far as i remember my first post oon this group
    was on related things - i mean the problem that c cupports those modules
    but dont support module names and it may simply make crash or clask of symbols


    note i was not saying anything on 'proper module scheme', imo you could
    say thet support for modules in c is weak (as it is), but c allows you
    to ocomplile thise modules , design them, store them, link them etc,
    write web pages on them and so on

    im not sure in old times i wouldnt be able to make this language mistake
    and say "c has no modules", maybe i could and maybe i did it myself ,
    maybe not (coz i rather kknew things like .o or .obj are modules so
    maybe not but im not sure).. today i thing its better to say 'c support
    for modules is weak ' than 'c has not a modules'

    but this is out of context coz if someone assumes he talks on some
    heavier module support in code c dont has it - but i was sayin im
    talking about this 'c has no modules' out of context..out of specific
    context it has weak support for modules (at leat implementations have it)

    --- 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 Mon Sep 14 15:01:14 2026
    Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:
    Ike Naar <ike@sdf.org> writes:
    On 2026-09-12, bart <bc@freeuk.com> wrote:
    Note that the code will still have braces. I suggest a better aim is to >>> eliminate most braces. The should be no need to ever see '} else {'
    instead of just 'else'.

    There can be a difference; for example (assume <stdio.h> included):

    if (0) { if (1) puts("foo"); else puts("bar"); }

    if (0) { if (1) puts("foo"); } else { puts("bar"); }

    The first line will print nothing; the second one will print "bar".

    I believe bart was suggesting a language change, not offering advice
    on how to program in C.

    In C, the syntax for an "if" statement is:

    if ( expression ) statement
    if ( expression ) statement else statement

    (C23 tweaks this very slightly in ways that are not relevant to
    the current discussion.) Since it's defined in terms of single
    statements, if you want multiple statements in a branch you need to
    create one by enclosing multiple statements in braces. This also
    requires a rule about which "if" a given "else" is associated with.

    Many other langauges allow multiple statements where C only allows
    a single statement. They typically do so by requiring a closing
    delimiter matching the "if", for example "endif", "end if", "end",
    or "fi". They also typically add a single token combining "else"
    and "if", typically "elseif", "elsif", or "elif".

    (Pascal follows the C approach, but spells "{" and "}" as "begin"
    and "end".)

    It's not practical to follow bart's advice (always use "else" rather
    than "} else {" unless you're using some language other than C.

    bart's point, I think, is that he dislikes the way C does this.

    Personally, I tend to prefer the non-C delimited approach, since
    it's a bit less error-prone, but both approaches are perfectly
    valid and can be used cleanly and correctly with a little care.
    It's not a factor I consider when deciding which language to use.

    I simply always use braces, regardless of whether or not
    the clause contains a single statement or a compound statement.


    --- 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 14 18:11:34 2026
    On 14/09/2026 17:01, Scott Lurndal wrote:
    Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:

    Personally, I tend to prefer the non-C delimited approach, since
    it's a bit less error-prone, but both approaches are perfectly
    valid and can be used cleanly and correctly with a little care.
    It's not a factor I consider when deciding which language to use.

    I simply always use braces, regardless of whether or not
    the clause contains a single statement or a compound statement.


    That's always a safe choice, but some C programmers prefer to use fewer braces. A compromise is to insist on always using braces if there is an "else" clause (in both the "if" and "else" parts), or at the very least,
    to do so if there are nested "if" statements.

    Always using braces (combined with a consistent indent style) is the
    choice with the lowest risk of mistakes or misinterpretation, and means
    that changes such as adding or removing statements to the controlled
    parts do not lead to additional changes. For anyone using version
    control systems, the advantage of :

    if (test) {
    do_this();
    }

    over :

    if (test)
    do_this();

    is obvious the first time they need to change the code to :

    if (test) {
    do_this();
    do_that();
    }


    Still, the important thing is writing the code in a good, clear manner, regardless of what the language allows or does not allow.


    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From tTh@3:633/10 to All on Mon Sep 14 20:21:51 2026
    On 9/14/26 18:11, David Brown wrote:

    I simply always use braces, regardless of whether or not
    the clause contains a single statement or a compound statement.


    That's always a safe choice, but some C programmers prefer to use fewer braces.˙ A compromise is to insist on always using braces if there is an "else" clause (in both the "if" and "else" parts), or at the very least,
    to do so if there are nested "if" statements.

    About braces, I always use them except in one case :
    when the code fragment is on the same line as the if.

    if (retval) fprintf(stderr, "retval is %d\n", retval);

    I think it's dangerous, but for some little things
    like my sample, it make things clearer for me.

    --
    ** **
    * tTh des Bourtoulots *
    * http://maison.tth.netlib.re/ *
    ** **

    --- 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 Mon Sep 14 18:54:34 2026
    David Brown <david.brown@hesbynett.no> writes:
    On 14/09/2026 17:01, Scott Lurndal wrote:
    Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:

    Personally, I tend to prefer the non-C delimited approach, since
    it's a bit less error-prone, but both approaches are perfectly
    valid and can be used cleanly and correctly with a little care.
    It's not a factor I consider when deciding which language to use.

    I simply always use braces, regardless of whether or not
    the clause contains a single statement or a compound statement.


    That's always a safe choice, but some C programmers prefer to use fewer >braces. A compromise is to insist on always using braces if there is an >"else" clause (in both the "if" and "else" parts), or at the very least,
    to do so if there are nested "if" statements.

    Always using braces (combined with a consistent indent style) is the
    choice with the lowest risk of mistakes or misinterpretation, and means
    that changes such as adding or removing statements to the controlled
    parts do not lead to additional changes. For anyone using version
    control systems, the advantage of :

    if (test) {
    do_this();
    }

    over :

    if (test)
    do_this();

    is obvious the first time they need to change the code to :

    if (test) {
    do_this();
    do_that();
    }


    That's true for anyone still using 80-column punched cards
    (or ancient line-oriented editors) as well.

    :-)

    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Kaz Kylheku@3:633/10 to All on Mon Sep 14 19:14:31 2026
    On 2026-09-10, Chris M. Thomasson <chris.m.thomasson.1@gmail.com> wrote:
    On 9/9/2026 5:43 AM, David Brown wrote:
    [...]
    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.

    ________
    #ifndef __NUMBER_GENERATOR_H__
    #define __NUMBER_GENERATOR_H__ 1
    ________


    Is that __* non conformant? Does it breach the impl name prefix space?

    No matter what you name anything in C, you are playing roulette.
    Vendor extensions and new standard features introduce identifiers into namespaces that have not been hitherto reserved.

    It's like a traffic code. If you intrude into a namespace, it's like
    running a stop sign. Nothing bad might happen, but if it does, it is
    on you.

    However, C naming is like a residential neighborhood full of unguarded intersections, with only a few stop signs.

    There isn't anything reasonable you can do to 100% ensure you will never
    have a clash with anything in your C programming. (By "reasonable",
    I do not intend to introduce moving goalposts: specifically, I mean,
    not subjecting yourself to some horribly inconvenient naming scheme in
    every single namespace which makes it vanishingly improbable of ever
    seeing a clash).

    --- 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 14 22:54:05 2026
    On 14/09/2026 20:21, tTh wrote:
    On 9/14/26 18:11, David Brown wrote:

    I simply always use braces, regardless of whether or not
    the clause contains a single statement or a compound statement.


    That's always a safe choice, but some C programmers prefer to use
    fewer braces.˙ A compromise is to insist on always using braces if
    there is an "else" clause (in both the "if" and "else" parts), or at
    the very least, to do so if there are nested "if" statements.

    ˙˙ About braces, I always use them except in one case :
    ˙˙ when the code fragment is on the same line as the if.

    ˙˙ if (retval) fprintf(stderr, "retval is %d\n", retval);

    ˙˙ I think it's dangerous, but for some little things
    ˙˙ like my sample, it make things clearer for me.


    I do the same, but restrict it to simpler statements.

    "Simpler" is a matter of taste and subjective judgement here -
    "return;", "break;", "continue;" are all "simple". A short assignment
    is "simple". For a longer printf, I'd usually use braces. If the
    statement is too long to be comfortable on one line, or may reasonably
    become so in future modifications, then I'd have braces.



    --- 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 14 22:55:53 2026
    On 14/09/2026 20:54, Scott Lurndal wrote:
    David Brown <david.brown@hesbynett.no> writes:
    On 14/09/2026 17:01, Scott Lurndal wrote:
    Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:

    Personally, I tend to prefer the non-C delimited approach, since
    it's a bit less error-prone, but both approaches are perfectly
    valid and can be used cleanly and correctly with a little care.
    It's not a factor I consider when deciding which language to use.

    I simply always use braces, regardless of whether or not
    the clause contains a single statement or a compound statement.


    That's always a safe choice, but some C programmers prefer to use fewer
    braces. A compromise is to insist on always using braces if there is an
    "else" clause (in both the "if" and "else" parts), or at the very least,
    to do so if there are nested "if" statements.

    Always using braces (combined with a consistent indent style) is the
    choice with the lowest risk of mistakes or misinterpretation, and means
    that changes such as adding or removing statements to the controlled
    parts do not lead to additional changes. For anyone using version
    control systems, the advantage of :

    if (test) {
    do_this();
    }

    over :

    if (test)
    do_this();

    is obvious the first time they need to change the code to :

    if (test) {
    do_this();
    do_that();
    }


    That's true for anyone still using 80-column punched cards
    (or ancient line-oriented editors) as well.

    :-)

    I don't quite follow you. (I use line lengths up to perhaps 120
    characters, but not rigidly fixed.)


    --- 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 Mon Sep 14 21:03:52 2026
    David Brown <david.brown@hesbynett.no> writes:
    On 14/09/2026 20:54, Scott Lurndal wrote:
    David Brown <david.brown@hesbynett.no> writes:
    On 14/09/2026 17:01, Scott Lurndal wrote:
    Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:

    Personally, I tend to prefer the non-C delimited approach, since
    it's a bit less error-prone, but both approaches are perfectly
    valid and can be used cleanly and correctly with a little care.
    It's not a factor I consider when deciding which language to use.

    I simply always use braces, regardless of whether or not
    the clause contains a single statement or a compound statement.


    That's always a safe choice, but some C programmers prefer to use fewer
    braces. A compromise is to insist on always using braces if there is an >>> "else" clause (in both the "if" and "else" parts), or at the very least, >>> to do so if there are nested "if" statements.

    Always using braces (combined with a consistent indent style) is the
    choice with the lowest risk of mistakes or misinterpretation, and means
    that changes such as adding or removing statements to the controlled
    parts do not lead to additional changes. For anyone using version
    control systems, the advantage of :

    if (test) {
    do_this();
    }

    over :

    if (test)
    do_this();

    is obvious the first time they need to change the code to :

    if (test) {
    do_this();
    do_that();
    }


    That's true for anyone still using 80-column punched cards
    (or ancient line-oriented editors) as well.

    :-)

    I don't quite follow you. (I use line lengths up to perhaps 120
    characters, but not rigidly fixed.)

    If the braces weren't there in the original source, one would
    need to repunch one card and add two[*]. Rather than just
    sliding the one new card in the appropriate place in the deck.

    Likewise with a line-mode editor - you'd need to edit three lines
    instead of adding one.


    [*] or add three cards instead of modifying the if card.

    --- 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 14 23:56:41 2026
    On 2026-09-14 22:54, David Brown wrote:
    On 14/09/2026 20:21, tTh wrote:
    On 9/14/26 18:11, David Brown wrote:

    I simply always use braces, regardless of whether or not
    the clause contains a single statement or a compound statement.


    That's always a safe choice, but some C programmers prefer to use
    fewer braces.˙ A compromise is to insist on always using braces if
    there is an "else" clause (in both the "if" and "else" parts), or at
    the very least, to do so if there are nested "if" statements.

    ˙˙˙ About braces, I always use them except in one case :
    ˙˙˙ when the code fragment is on the same line as the if.

    ˙˙˙ if (retval) fprintf(stderr, "retval is %d\n", retval);

    I have the habit to regularly use a line-break and indentation here.

    if (retval)
    fprintf(stderr, "retval is %d\n", retval);

    ˙˙˙ I think it's dangerous, but for some little things
    ˙˙˙ like my sample, it make things clearer for me.

    I wouldn't exactly call it "dangerous". But I think one should apply
    any means and habits that avoid the errors that one personally knows
    to make.

    For collaborative work we therefore had a rule to always use braces.


    I do the same, but restrict it to simpler statements.

    "Simpler" is a matter of taste and subjective judgement here -
    "return;", "break;", "continue;" are all "simple".˙ A short assignment
    is "simple".˙ For a longer printf, I'd usually use braces.˙ If the
    statement is too long to be comfortable on one line, or may reasonably become so in future modifications, then I'd have braces.

    For specific "simple statements" like early exits I usually even add
    an empty line after it;

    if (!precond)
    return special;

    regular_process;

    For 'if'-cascades with "simple statements" I also omit the line-break,
    though. As you say it's also about any specific code being comfortably represented.

    Being a personal preference one should use a style to minimize problems
    in one's own style, or follow the company standards where collaborative
    work is expected.

    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 Tue Sep 15 00:33:05 2026
    On 2026-09-14 20:54, Scott Lurndal wrote:
    David Brown <david.brown@hesbynett.no> writes:
    On 14/09/2026 17:01, Scott Lurndal wrote:
    Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:

    Personally, I tend to prefer the non-C delimited approach, since
    it's a bit less error-prone, but both approaches are perfectly
    valid and can be used cleanly and correctly with a little care.
    It's not a factor I consider when deciding which language to use.

    I simply always use braces, regardless of whether or not
    the clause contains a single statement or a compound statement.


    That's always a safe choice, but some C programmers prefer to use fewer
    braces. A compromise is to insist on always using braces if there is an
    "else" clause (in both the "if" and "else" parts), or at the very least,
    to do so if there are nested "if" statements.

    Always using braces (combined with a consistent indent style) is the
    choice with the lowest risk of mistakes or misinterpretation, and means
    that changes such as adding or removing statements to the controlled
    parts do not lead to additional changes. For anyone using version
    control systems, the advantage of :

    if (test) {
    do_this();
    }

    over :

    if (test)
    do_this();

    is obvious the first time they need to change the code to :

    if (test) {
    do_this();
    do_that();
    }

    I sometimes hear that as argument but to me it had never been a
    convincing one. - If I change my program in any way, complex or
    (as here) trivially, I always inspect the context and make the
    necessary adjustments. For me there's no need to add spurious
    syntactical elements, visually polluting ballast, in the first
    place. YMMV.

    It's another thing if one is working in a collaborative context,
    and/or using an "IDE" that will automatically create appropriate
    (though still spurious) braces when you enter keywords.


    That's true for anyone still using 80-column punched cards
    (or ancient line-oriented editors) as well.

    :-)

    Okay, I see the smiley, but I don't see the relation to what was
    quoted.

    Concerning your statement per se; restricting your column-width
    in programs adds to legibility! - I recall my *cough* Java times
    where line lengths of a (rare) minimum of 120, and more typical
    lengths of 160-200+, was the "standard" - code really horrible to
    read.

    Personally I use the classical 80-column width as _soft hint_ that
    I try to not exceed. - A quick browse over some sources shows that
    typical lengths of the longer lines are around 50-60 columns, and
    lines >80 are rare, and >100 even much rarer.

    BTW, yes I've used punch-cards (and still have a stack somewhere)
    but the habit of using not too long lines did not stem from there.
    It is just a matter of legibility (and thus maintenance); again,
    beyond personal preferences, especially in collaborative working
    environments.

    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 Mon Sep 14 23:41:05 2026
    On 14/09/2026 08:41, Waldek Hebisch wrote:
    bart <bc@freeuk.com> wrote:

    As I wrote, there is inheritance which is used much more frequently
    than import. And import means that all functions from imported
    module may be used without qualification. That is if module A
    exports function f, than after importing A I can just write 'f()'
    to call 'f' (assuming it needs no arguments).
    ....> As I wrote I can use equvalent of M.A() without import.

    Do you mean that you can call imported function A() without importing
    its owner module M()?

    Above (in the example that uses A.f() instead of M.A()) you suggest the
    module name must be explicitly exported.

    Otherwise there must be some other approach for the compiler to know
    what imports are to be done. (I think some schemes are file-based: eg.
    all source files in the current directory are assumed to be project
    modules.)


    In my case import means that functions are available without
    qualification, so plain E() may call function from imported module.
    And I have function overloading and partial type inference. In
    effect, it is not entirely trivial to decide which function is
    actually called when you write E(). Most functions either needs
    arguments or produces values (or both), so calling wrong functions
    almost surely is not a big problem, that is either overloading
    machinery would choose the correct one, or call to wrong one will
    result in type error. But still, I think that is better to limit
    possible confusion and import as little as possible.

    My language only allows one top-level name E in scope at any one
    location. If two imported modules both export E, then the compiler will complain; they need to be disambiguated.

    There is also shadowing, so here it is possible to mistakenly call a
    local function that happens to have the same name and signature.

    But such problems are well-known when you have nested scopes, and you
    see them in other languages too.


    More generally, I also worked with dynamic languages where one
    simply calls a function and types of arguments are only checked
    on use. IME code in such languages needs a lot of testing, much
    more than with type checking. That is without type checking
    it is too easy to ship code which calls a function with argument
    of wrong type. Clearly to check types compiler must know them.
    And absent total type reconstrution (like in ML), one needs to
    declare types of arguments and return type of functions.
    So I hope that is part is clear.

    I have a lot of experience of dynamic languages that ran at customer
    sites. Such language errors were extremely rare.

    It's not that I did extensive testing, but with normal development over
    a longish time-frame (eg. 1-2 years), you will uncover a lot of bugs!


    You may doubt necessity of having duplicate declaration in the
    module interface. In principle compiler could do all needed
    checks having only single declaration. But compilers that I
    use need declaration in interface part. And when reading code I
    actually prefer to have both declarations. Namely, when looking
    at interactions between modules I look at interface parts and
    want to see relevant declarations there.

    The duplicate declarations are necessary in some situations. For example
    you don't have the implementation source code, but that info is
    necessary to be able to use those exports in your program.

    However, they could be automatically generated by whoever /does/ have
    the source code, by a compiler option.


    When working on inner
    part of module I want relevant info there. For example, I disliked
    standard Pascal rule that forward declaration contained all
    info, but corresponding defintion contained just function name
    skipping arguments types and names. For me extra effort during
    reading, due to extral lookup for missing info meant more work
    compared to cut-and-paste needed to duplicate function header.

    I don't remember that in Pascal. However I remember similar schemes from
    my own early languages. Functions were routinely declared in advance,
    whether necessary or not (I didn't want to worry about definition order).

    But the declaration contained only the parameter types, and the
    definition contained only the parameter names! I recently rediscovered
    this fact and wondered how I tolerated it.


    Type inference means
    almost no reduction in ability to detect errors and some reduction
    of work in maintaining declarations. At least in case of C and
    C++ type inference optional: you can still give explicit types.
    At least your description of of your module system suggest that
    it is more like FORTRAN than modern type interface.

    Type inference and modules are different things. Modules manage
    visibility named entities including types across source files.

    Sure. I mentioned type inference to illustrate that approach may
    change and if compiler can infer needed information, then languages
    may depend on this saving programmer work. But gross rules like
    firt letter rule of old FORTRAN (or implicit int from traditional
    C) are unsatisfactory. And when talking about modules your
    rule "all modules are visible" looks more like old gross rules and
    unlike inference process.

    Well, all functions and other top-level names are visible everywhere
    inside one module. That is not usually considered a problem.

    Since you mentioned big modules, I will say that in my old stuff, one
    module had 7K lines (an interpreter core), and another nearly 6K (a
    one-pass bytecode compiler), although bloated by inline assembly.

    This is basically taking such a module and splitting it up into N
    chunks. Entities used in more than one chunk need to be shared.

    C uses the 'linkage' system for functions and variables. It uses text
    replication to share entities such as types, structs, enumerations and
    macros. How do other language's modules cope with the latter?

    Typical approach is to have compiled version of interface. That
    requires some method to write such info to files. IIUC GNU C
    precompiled headers use (or used) crude but simple method: they
    just dumpled memory area containing intenal compiler representation
    of the header. This is simple and fast, but any tiny mismatch could
    lead to error, so this mechanizm has serious limitations and is
    unsuitable for use with modules. GNU Pascal walked internal tree
    of nodes, keeping visted nodes in a hash table to make sure that
    needed node is stored exactly one. During storing each node was
    assigned integer identifier and all pointers were repleaced by
    identifiers (numbers) of taget node. Reading worked in reverse:
    it re-build nodes in memory, replacing numeric indentifiers by
    pointers.

    The system I mentioned above writes interface information in textual
    form, but it is easier to parse and more explicit than source code.

    I was asking more about managing the names of variables, types etc
    across modules. In C that is very crude, and it can be unintuitive.

    As I do it, all of these named, top-level entities:

    functions
    variables
    named constants
    enumerations
    user-defined types and records
    macros

    are handled in the same way: stick 'global' or 'export' in front of the definitions, and it makes the names visible outside the module.

    I was asking if the same applied to other languages.


    This is that 215Kloc project? 300s (approx time for single core) is
    pretty slow for that. What is the problem here; the language being hard
    to process?

    In addition compiler uses linear search in symbol table.

    Actually I use linear searching extensively too. Except in the global
    symbol table which is a hash-table. So lexical lookups use that, but
    resolving a generic identifier into a special one uses linear methods.

    Generally it is still very fast because the lists are short. But some
    programs could cause it trouble.

    Getting rid of recursion and implied by this multiple re-compilation
    probably would give 3-5 times faster compilation (and hopefully
    would eliminate really bad cases). If things could be simplified
    so that hash table is enough, that probably would double speed.
    Once that is handled other things would requre attention. But
    it does not make much sense to fight for small speedups in other
    places when biggest issues (that is recursive compilation and
    linear search are unresolved). And that require substantial
    rework. Even after rework compiler is unlikly to be as fast as
    yours. Namely overloading and type inference

    So, is type inference (eg. Hindley-Milner) inherently slow?

    Also, compiler is using higher level data structures that
    has its own costs. Parsing this 215K wc lines takes 1 second,
    while it should be possible to do this in 0.1 second. But
    again, before other issues are handled relative gain from
    faster parser is too small to bother (I may speed up parser
    if I need to reorganize it to implement some extra feature).

    BTW: It is hard to compare compile speed in longer time because
    machines got faster. But when I started my work build needed
    something like 2.5 hours,

    I would never have tolerated that. I considered it part of my job to
    make sure my tools stayed productive whatever the hardware.


    When I need to look at preprocessed files I frequently see a lot of
    blank lines, so I am not surprised that headers get smaller. At first
    glance 4000 lines after preprocessing looks too small, but maybe it
    is real.

    I can tell you that 1/3 of my processing type is to do with comments.
    (After stripping them it took 2/3 as long.) So I might look at how
    efficiently that is done, for a start. But there is a lot of mystery still.

    This output is not enough to use as a new compact header; it will need
    #defines etc that have been stripped. But it shows the core of the API
    is quite small. I will investigate further.)

    At some time I did a little work on Mac OS API. There was about
    220 tousends symbols, of which something like 200 tousends where
    various magic constants. So, maybe bulk od SDL3 headers is due
    to defiend constants?

    From the end result (via a tool to convert to my bindings), there are
    about 500 #defines and 1100 enum names. But probably there are lots of duplicates in the headers, some may be in 'dead' blocks. And some
    headers are processed more than once.

    It's messy, but it seems a big downside of C's 'module' scheme!

    And of course, all the work has to be repeated for each file that
    includes SDK.h.



    --- 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 15 01:48:10 2026
    bart <bc@freeuk.com> wrote:
    On 14/09/2026 08:41, Waldek Hebisch wrote:
    bart <bc@freeuk.com> wrote:

    As I wrote, there is inheritance which is used much more frequently
    than import. And import means that all functions from imported
    module may be used without qualification. That is if module A
    exports function f, than after importing A I can just write 'f()'
    to call 'f' (assuming it needs no arguments).
    ....> As I wrote I can use equvalent of M.A() without import.

    Do you mean that you can call imported function A() without importing
    its owner module M()?

    Yes, but only using quailfied name, in your notation A.A()

    Above (in the example that uses A.f() instead of M.A()) you suggest the module name must be explicitly exported.

    Anything not exported is invisible from outside of given module.
    So you need to export a name to use it from outside.

    Otherwise there must be some other approach for the compiler to know
    what imports are to be done. (I think some schemes are file-based: eg.
    all source files in the current directory are assumed to be project modules.)

    Compiler has info about exported things from all "standard" modules
    (that is distributed with the compiler), this info is collected at
    system build time. If you compile a new nonstandard module it is
    then usable for import in given invocation of the compiler. You
    can also tell the compiler about previously compiled modules.

    So at any given time compiler has list of modules it considers valid.
    Beside module name it also contains information where to find
    compiled code of the module.

    In my case import means that functions are available without
    qualification, so plain E() may call function from imported module.
    And I have function overloading and partial type inference. In
    effect, it is not entirely trivial to decide which function is
    actually called when you write E(). Most functions either needs
    arguments or produces values (or both), so calling wrong functions
    almost surely is not a big problem, that is either overloading
    machinery would choose the correct one, or call to wrong one will
    result in type error. But still, I think that is better to limit
    possible confusion and import as little as possible.

    My language only allows one top-level name E in scope at any one
    location. If two imported modules both export E, then the compiler will complain; they need to be disambiguated.

    OK.

    There is also shadowing, so here it is possible to mistakenly call a
    local function that happens to have the same name and signature.

    But such problems are well-known when you have nested scopes, and you
    see them in other languages too.


    More generally, I also worked with dynamic languages where one
    simply calls a function and types of arguments are only checked
    on use. IME code in such languages needs a lot of testing, much
    more than with type checking. That is without type checking
    it is too easy to ship code which calls a function with argument
    of wrong type. Clearly to check types compiler must know them.
    And absent total type reconstrution (like in ML), one needs to
    declare types of arguments and return type of functions.
    So I hope that is part is clear.

    I have a lot of experience of dynamic languages that ran at customer
    sites. Such language errors were extremely rare.

    It's not that I did extensive testing, but with normal development over
    a longish time-frame (eg. 1-2 years), you will uncover a lot of bugs!

    I would say that normally it is rare to discover such bugs. Simply
    your program happily runs for 20 years and then you suddenly discover
    that some strange but valid input causes a crash.

    Also, I found it pretty common to have functions that are never
    called, which if called would crash. Since functions are never
    called you can not discover errors in them by testing.

    Why do I say this:
    1) when attemptin to modify old code I frequently see things which
    look strange. In many cases deeper egzamination shows that
    code is wrong.
    2) I also run a compiler which is doing deeper analysis and it
    reported several problems with old code.

    IIUC in commercial settings in the past there were tendency to
    disregard such problem ("if customer can not see a problem, then
    software is good enough").

    You may doubt necessity of having duplicate declaration in the
    module interface. In principle compiler could do all needed
    checks having only single declaration. But compilers that I
    use need declaration in interface part. And when reading code I
    actually prefer to have both declarations. Namely, when looking
    at interactions between modules I look at interface parts and
    want to see relevant declarations there.

    The duplicate declarations are necessary in some situations. For example
    you don't have the implementation source code, but that info is
    necessary to be able to use those exports in your program.

    However, they could be automatically generated by whoever /does/ have
    the source code, by a compiler option.

    Well, compiler must know what is exported. Usual way to provide
    this information is via duplicate declarations.

    When working on inner
    part of module I want relevant info there. For example, I disliked
    standard Pascal rule that forward declaration contained all
    info, but corresponding defintion contained just function name
    skipping arguments types and names. For me extra effort during
    reading, due to extral lookup for missing info meant more work
    compared to cut-and-paste needed to duplicate function header.

    I don't remember that in Pascal. However I remember similar schemes from
    my own early languages. Functions were routinely declared in advance, whether necessary or not (I didn't want to worry about definition order).

    But the declaration contained only the parameter types, and the
    definition contained only the parameter names! I recently rediscovered
    this fact and wondered how I tolerated it.


    Type inference means
    almost no reduction in ability to detect errors and some reduction
    of work in maintaining declarations. At least in case of C and
    C++ type inference optional: you can still give explicit types.
    At least your description of of your module system suggest that
    it is more like FORTRAN than modern type interface.

    Type inference and modules are different things. Modules manage
    visibility named entities including types across source files.

    Sure. I mentioned type inference to illustrate that approach may
    change and if compiler can infer needed information, then languages
    may depend on this saving programmer work. But gross rules like
    firt letter rule of old FORTRAN (or implicit int from traditional
    C) are unsatisfactory. And when talking about modules your
    rule "all modules are visible" looks more like old gross rules and
    unlike inference process.

    Well, all functions and other top-level names are visible everywhere
    inside one module. That is not usually considered a problem.

    If top-level internal names are visible everywhere inside one
    module, that is OK. With imported names it is borderline.
    That is module A may export 100 functions of which 10 are needed
    inside function f and not needed outside. 100 functions pollute
    name space. Selecively importing 10 requires some work and still
    makes then visible in places where they are not needed. In such
    case best solution is import at function level, that is imported
    names are only visible within function f.

    Since you mentioned big modules, I will say that in my old stuff, one
    module had 7K lines (an interpreter core), and another nearly 6K (a
    one-pass bytecode compiler), although bloated by inline assembly.

    This is basically taking such a module and splitting it up into N
    chunks. Entities used in more than one chunk need to be shared.

    C uses the 'linkage' system for functions and variables. It uses text
    replication to share entities such as types, structs, enumerations and
    macros. How do other language's modules cope with the latter?

    Typical approach is to have compiled version of interface. That
    requires some method to write such info to files. IIUC GNU C
    precompiled headers use (or used) crude but simple method: they
    just dumpled memory area containing intenal compiler representation
    of the header. This is simple and fast, but any tiny mismatch could
    lead to error, so this mechanizm has serious limitations and is
    unsuitable for use with modules. GNU Pascal walked internal tree
    of nodes, keeping visted nodes in a hash table to make sure that
    needed node is stored exactly one. During storing each node was
    assigned integer identifier and all pointers were repleaced by
    identifiers (numbers) of taget node. Reading worked in reverse:
    it re-build nodes in memory, replacing numeric indentifiers by
    pointers.

    The system I mentioned above writes interface information in textual
    form, but it is easier to parse and more explicit than source code.

    I was asking more about managing the names of variables, types etc
    across modules. In C that is very crude, and it can be unintuitive.

    As I do it, all of these named, top-level entities:

    functions
    variables
    named constants
    enumerations
    user-defined types and records
    macros

    are handled in the same way: stick 'global' or 'export' in front of the definitions, and it makes the names visible outside the module.

    At source code level typical practice is to have module interface,
    everthing declated there is exported. At implementation level
    this can be handled by setting a flag, (say 'export') for things in
    the interface, and no export for implementation part.

    Extended Pascal has rather over-engineered system: module may have
    multiple interfaces. Everthing declared in module interface part
    may be exported, but to really export it you need to declare a
    interface and list all names exported by this interface. This has
    some advantages, for example you can export a function without
    exporting type of return value or types of arguments. But
    implementation is complex and in use it is tedious to provide
    list of exported names. And in practice module frequently have
    only a single interface, so declaration(s) of interfaces add
    unnecessary clutter. GNU Pascal made it a bit simpler, instead
    of providing list of names you could write keyward 'all' meaning
    list of all things defined in the interface, or 'all' with exclusions.

    I was asking if the same applied to other languages.


    This is that 215Kloc project? 300s (approx time for single core) is
    pretty slow for that. What is the problem here; the language being hard
    to process?

    In addition compiler uses linear search in symbol table.

    Actually I use linear searching extensively too. Except in the global
    symbol table which is a hash-table. So lexical lookups use that, but resolving a generic identifier into a special one uses linear methods.

    Generally it is still very fast because the lists are short. But some programs could cause it trouble.

    Typically lists are short, except when they are not. Due to inheritance
    a single import can pull hundreds of names. And I mentioned that
    modules may have parameters which are again modules. Corresponding
    interface is automatically imported. So, even though number of
    explicit import lines is relatively small, compiler actually pulls
    a lot of stuff into symbol table. Also, beside imports also some
    compiler internal stuff goes into symbol table. So, length of list
    easily goes into low thousends. And compiler makes a lot of searches.

    I profiled several compiler runs and typically 45-50% of time goes
    into linear search and other 5% goes into hash table access (which
    handles majority of cases, but not all). So I _know_ that linear
    search take time. Note: I also know that there is huge number
    of seaches. Compiler that uses seaches more sparingly could be
    much faster (and my improvement eliminated some searches, but
    I reached point where deeper change is needed).

    Getting rid of recursion and implied by this multiple re-compilation
    probably would give 3-5 times faster compilation (and hopefully
    would eliminate really bad cases). If things could be simplified
    so that hash table is enough, that probably would double speed.
    Once that is handled other things would requre attention. But
    it does not make much sense to fight for small speedups in other
    places when biggest issues (that is recursive compilation and
    linear search are unresolved). And that require substantial
    rework. Even after rework compiler is unlikly to be as fast as
    yours. Namely overloading and type inference

    So, is type inference (eg. Hindley-Milner) inherently slow?

    Hindley-Milner is different story. There are hostile programs
    where it can take long time, but in practice it seem to be
    reasonably fast. But above main issue is overloading. Consider
    simple C expression like:

    a = f(1, 2, 3);

    In C you will have 1 or 0 symbol table entries for f. If there
    is 1 entry, than you check that argument types match and return
    type is appriate for assingment to a. Otherwise yoy report error.
    Now, let us switch to C++. You may have say 10 symbol table entries
    for f and you essentially need to check them all to decide that
    any is applicable. And look at more complicated case:

    a = f(g(), h(i(), j(k(), l())));

    If you have 10 possiblities for f, 10 for g, etc, then naive seach
    may have to go trough million combinations to find the right one.
    There are smarter approaches than naive recursive search, but
    if you have say 10 possibilites on average, than 10 times slowdown
    at this stage looks unavoidable. Actually, for single call
    average number of possibilites seem to be smaller, but even with
    smarter approach it grows for more complicated expressions.
    And smarter approach requires more complicated data structures,
    so there will be some overhead.

    In the sytem I mentioned type inference is in the style of C and C++
    'auto' which AFAICS can be pretty cheap for C, basically you take
    return type of f as type of a. But type inference means that simple
    pruning like only looking at f which have right return type does not
    work.

    Also, compiler is using higher level data structures that
    has its own costs. Parsing this 215K wc lines takes 1 second,
    while it should be possible to do this in 0.1 second. But
    again, before other issues are handled relative gain from
    faster parser is too small to bother (I may speed up parser
    if I need to reorganize it to implement some extra feature).

    BTW: It is hard to compare compile speed in longer time because
    machines got faster. But when I started my work build needed
    something like 2.5 hours,

    I would never have tolerated that. I considered it part of my job to
    make sure my tools stayed productive whatever the hardware.

    I spent nontrivial effort on making compiler faster. But in slightly
    different spirit I can say that need for build is not that frequent.
    Namely, typical module can be recompiled independently from other
    modules and tested. So full build is only needed to initally create
    binary and to verify absence of weird interations not cought by
    earlier testing. And for creating binaries I developed a process
    that used machine independent result of compilation only doing
    machine dependent part. Of course, you still needed to run full
    build first to build machine independent part. But other folks
    could use the result which allowed them faster creation of binaries.

    At some stages I used multiple machines, when one machine was
    doing build I was doing something else on other machine.

    So, I worked on making compiler faster and I developed workarounds
    that make slow speed tolarable.

    Let me mention that one of speed improvements is quite recent.
    I spent semething like 2-3 days to shorten real time of parallel
    build from about 60s to 45s (that involves more than compilation,
    so is longer than just compile time). Comparing the two things
    it seems that I will need about 5000 builds to recover time
    that I spent on speeding up the build. Given that I am doing
    some hundreds of builds per year, it will take several years
    to recover the time. There are other folks doing build and
    they will benefit too (but probably less than myself because
    with smaller number of cores gain is smaller). But AFAICS in
    commercial setting I could not justify time spend on speeding
    up build: "present value" of differce between effort and
    gain is negative.

    When I need to look at preprocessed files I frequently see a lot of
    blank lines, so I am not surprised that headers get smaller. At first
    glance 4000 lines after preprocessing looks too small, but maybe it
    is real.

    I can tell you that 1/3 of my processing type is to do with comments.
    (After stripping them it took 2/3 as long.) So I might look at how efficiently that is done, for a start. But there is a lot of mystery still.

    I see.

    This output is not enough to use as a new compact header; it will need
    #defines etc that have been stripped. But it shows the core of the API
    is quite small. I will investigate further.)

    At some time I did a little work on Mac OS API. There was about
    220 tousends symbols, of which something like 200 tousends where
    various magic constants. So, maybe bulk od SDL3 headers is due
    to defiend constants?

    From the end result (via a tool to convert to my bindings), there are
    about 500 #defines and 1100 enum names. But probably there are lots of duplicates in the headers, some may be in 'dead' blocks. And some
    headers are processed more than once.

    It's messy, but it seems a big downside of C's 'module' scheme!

    And of course, all the work has to be repeated for each file that
    includes SDK.h.



    --
    Waldek Hebisch

    --- 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 15 02:42:55 2026
    bart <bc@freeuk.com> wrote:
    On 14/09/2026 08:41, Waldek Hebisch wrote:
    bart <bc@freeuk.com> wrote:

    A more typical problem is organising the functions, variables, types,
    enums and tables of an application into multiple modules: what goes
    where; what needs to be shared.

    You may view interface as information about what needs to be shared,
    but IMO there is more to this. In badly designed program a lot
    must be shared. In well designed program and assuming that problem
    domain is suitable for modularization sharing is quite limited.
    And frequently is is possible to replace implementation part by
    quite a different thing without affectiong correctness of the
    program.

    To make a concrete example, I needed simple varianat of regular
    expressions. In principle I could call existing library via FFI, but
    that had its own problems. Since the core algorithm is quite simple
    I decided to roll my own. I ended with collection of 4 modules.
    One module implements a single node of automation, second one
    implements matching algorithm and build automation (that is graph
    of nodes) from other data. Third module provides a higher level
    abstractions, representing patterns build from simpler automatons
    via boolean operations. Fourth module contains a parser which
    converts textual patterns to internal representation, using
    operations provided by earlier modules. Together this is 452
    wc lines. One may be tempted to do this a single module, but
    I think that what I did have better structure: first module
    essentially defines data struture (or maybe I should say data
    type) and in principle this could be part of the second module.
    But having module means that some things are hidden and some
    are exported in nicer form. So I do not consider having this
    as a separtate module as a big deal, but I think that overall
    thanks to this code is a little nicer. Second module implements
    core algorithm. IMO is is nice that this code is not mixed
    with other parts and also it is potentially reusable in the
    future. Third module implements feature that I needed, it
    is something that AFAIK is not supported by standard libraries
    so I would need it even if I decided to scrap the first two
    modules and replace them by FFI calls to some standard library.
    The actual syntax of supported patterns is confined to the
    fourth module. If I needed different syntax (possibly with
    different featurs set) I can provide an alternative parser
    module. As you later write those are "friendly" modules
    designed to work together. But each of them have reasonably
    well specified responsibilities. And since responsiblity
    of each module is rather narrow, each of them is simple,
    almost trivial. Functionality provided by this collection
    of 4 modules is not very impressive, but less trivial than
    each of the involved modules.

    So let's say I implement this as four modules node.m, match.m,
    patterns.m, parser.m.

    Since they are really one unit, then anything that needs to be shared between them is marked 'global' to export, but see below.

    How they are imported depends on how they are to be used. They could be casually added to the modules of my application. Then I add these lines
    to its project info:

    module node
    module match
    module patterns
    module parser

    I can access its exported names directly without a qualifier as F(), or
    I can use mode.F(), parser.F() etc depending on where it lives.

    This forms part of my app and will be compiled as part of the
    whole-program build.

    However this is too casual: there is no real connection between it my
    and my own app. I can also see names shared across the four modules
    which are meant to be private (and it can access names in /my/ app!).

    So probably this would be made into its own subprogram. It will need its
    own module info, either added to one designated module, or more usually
    in a dedicated lead module, say called rex.m, which contains those same lines:

    module node
    module match
    module patterns
    module parser

    A further change is that those 'global' attributes need to be changed to 'export' to make them visible outside.

    Now, in my app, I add this one line to the project info:

    import rex

    I can now still call F(), or qualify it as rex.F(); I no longer need to
    know where F exists. (However, exported names must be unique; I can't
    use both node.F() and match.F().)

    'rex' and its modules can no longer see my apps global names. Its source files however will still be compiled into my app.

    This case look similar to the following Turbo/GNU Pascal code:

    unit rex;
    interface
    uses node, match, patterns, parser;
    end

    Namely, since node, match, patterns, parser are imported in the
    interface part of the module all identifiers from them are exported
    from rex. I am writing this from memory, so the exact syntax may
    be slightly different, possibly one needs to add some extra keywords.

    The first case have some similarity to having someting like:

    unit globals;
    interface
    uses ..., node, match, patterns, parser, ...;
    end

    that is creating a module that import all what is needed by the application. One difference is that in Turbo Pascal you would have to add

    uses globals;

    to each source file. Other difference is that modules see only things
    imported via 'uses'. And IIRC such global module defeats use of
    qualified name to distinguish finctions. That is qualified name
    would be globals.f. To use 'node.f' you need to directly import node.

    So that's two approaches to such a library that my scheme allows for.
    There is a third one: to put the library into its own DLL.

    The start point is the second approach, with rex.m and the four modules.
    But now I build it as a separate binary like this:

    mm -dll rex # creates rex.dll

    In my app, it now needs separate declarations which look like this:

    importdll rex =
    ... FFI declarations for rex's exports
    end

    This is not project info and can located anywhere. The declarations can
    be created in several ways:

    * Manually, but then they must keep track of any changes in the library

    * If rex was a C library, I can use a tool to do most of the work of creating this import block from a C header.

    * If written in my language, then 'mm -dll rex' will also write a
    suitable import module containing that 'importdll' block, either called rex_lib.m or rex.q depending on which of my two languages was
    configured. Then in my app's project info I can write one of:

    module rex_lib # (using rex.m would overwrite the rex.m original)
    module rex

    That exported function can still called as F(), or as rex_lib.F() or rex.F().

    I still build my app as 'mm app'; it will automatically pull in rex.dll.

    Turbo Pascal was before era of shared libraries and insisted that
    main program is in Turbo Pascal, so you could not use it to create
    libraries usable from other languages. With GNU Pascal one could
    just pass an option to create shared library and it create one. With
    proper extras (like C header files) the library was usable from
    any language. But really nice use from Pascal required some extra
    effort. Namely interface parts of modules provided declarations,
    but one had to add a special token so that compiler knew that
    implementation was in the library. But once creator of the library
    did its work it was transparent for the users, they just added
    appropriate 'uses' statement and compiler took care of the rest.
    That is normal module was compile and linked. Module from static
    library was statically linked. When module was in shared library
    the library was dynamically linked.

    There is one extra issue related to shared libraries, that is
    visibility. Quite typical case is that some symbols are
    "global" inside the shared library but should be invisible outside.
    GNU C has an attribute to control that. The same attibute could
    be used from GNU Pascal. IIUC your/Microsoft dll-something
    stuff serves similar purpose.

    What it doesn't do at the minute is write docs: collate doc-info from
    the exported module and write into a file to act as documentation.

    I used to have support for such doc-strings but dropped it due to lack
    of use.


    To summarise using this example 4-module library:

    (1) Add 4 'module' directives to my own app

    (2) Put them into rex.m then add 'module rex' to my app

    (3) Put them into rex.m, build as DLL, then add 'module rex/rex_lib'
    to my app

    This last will probably most appeal to you and corresponds most closely
    to your discrete interfaces. However it is more chaotic since it needs a separate set of declarations from from the definitions in the 4 modules.

    Actually in my case modules are dynamically loadable, so in a sense
    closest analogy would be to have 4 DLL-s. And one way of compiling
    for Windows would give you 4 real DLL-s. But PE headres are rather
    large, so this is rather bloated way. Different way uses different
    format which is much more space efficient.
    --
    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 15 07:39:27 2026
    I enjoy your extensive posts about modularization and about
    your practical reports in the area; very interesting. Thanks.

    On 2026-09-15 03:48, Waldek Hebisch wrote:
    bart <bc@freeuk.com> wrote:
    [...]
    I have a lot of experience of dynamic languages that ran at customer
    sites. Such language errors were extremely rare.

    It's not that I did extensive testing, but with normal development over
    a longish time-frame (eg. 1-2 years), you will uncover a lot of bugs!

    I would say that normally it is rare to discover such bugs. Simply
    your program happily runs for 20 years and then you suddenly discover
    that some strange but valid input causes a crash.

    (I know stories about proud folks who claim to have produced
    "error-free" software - because they were just not testing! ;-)

    [...]

    IIUC in commercial settings in the past there were tendency to
    disregard such problem ("if customer can not see a problem, then
    software is good enough").

    I hope not! Or, to put it in another way; my experience from
    "commercial settings" is that if they are doing professional
    software development and project management then they have
    installed various means of QA. - All the commercial companies
    I had worked in - with the exception of a small startup with
    only few members in the development area - had such extensive
    QA means installed, typically we had also own QA departments.

    [...]


    At some stages I used multiple machines, when one machine was
    doing build I was doing something else on other machine.

    When doing a lot of simulation back then we took advantage of
    the distributed workstations. Our processes polled the state
    (the actual load) of the various systems, and processes were
    spread to run on machines that had free capacities. (The only
    "problem" was that there were many in our department who did
    such runtime-demanding simulations, but in the end it overall
    payed; there's always a few systems being more or less idle.
    And the "management effort" was negligible [on Unix].)

    [...]

    [...] But AFAICS in
    commercial setting I could not justify time spend on speeding
    up build: "present value" of differce between effort and
    gain is negative.

    I'd say this very much depends on the project, and IT management.
    While it may be hard to estimate the gains - and the accumulated
    losses if you're not optimizing your processes! - we continuously
    worked on optimizations. It also motivates the developers; while
    the systems grew and got more complex the performance did not (not
    necessarily) decrease, but rather got often even better over time.

    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 15 09:07:06 2026
    On 14/09/2026 23:56, Janis Papanagnou wrote:
    On 2026-09-14 22:54, David Brown wrote:
    On 14/09/2026 20:21, tTh wrote:
    On 9/14/26 18:11, David Brown wrote:

    I simply always use braces, regardless of whether or not
    the clause contains a single statement or a compound statement.


    That's always a safe choice, but some C programmers prefer to use
    fewer braces.˙ A compromise is to insist on always using braces if
    there is an "else" clause (in both the "if" and "else" parts), or at
    the very least, to do so if there are nested "if" statements.

    ˙˙˙ About braces, I always use them except in one case :
    ˙˙˙ when the code fragment is on the same line as the if.

    ˙˙˙ if (retval) fprintf(stderr, "retval is %d\n", retval);

    I have the habit to regularly use a line-break and indentation here.

    ˙˙˙ if (retval)
    ˙˙˙˙˙˙˙ fprintf(stderr, "retval is %d\n", retval);


    To my eyes (and I fully appreciate that this kind of thing is highly subjective), that is the worst you can do. That's how you end up with mistakes like this, after lines are added, removed or changed during
    code maintenance :

    if (...)
    goto fail;
    goto fail;

    It gets even worse if different people have worked with the code and
    have different habits or settings for tabs and spaces. Suppose the
    first line of your code snippet had eight spaces, and the second line
    two tabs, written with someone using an "8 spaces per tab" setting.
    Someone looking at the code with "4 spaces per tab" will see them
    aligned and may assume the "fprintf" always runs.

    I believe it is good practice to write code that is clear regardless of
    the indents - and then use consistent indentation to make it even
    clearer. Even with tab/space muddles, there's no room for
    misinterpretation with either :

    if (retval) fprintf(stderr, "retval is %d\n", retval);

    or

    if (retval) {
    fprintf(stderr, "retval is %d\n", retval);
    }



    My indentation rule is very simple - end a line with { and everything afterwards is indented once, start a line with } and that line and
    everything afterwards is outdented once. The main exception is that if
    a single logical line has to be split over multiple lines because it is
    a long expression, there are at least two additional indents.

    ˙˙˙ I think it's dangerous, but for some little things
    ˙˙˙ like my sample, it make things clearer for me.

    I wouldn't exactly call it "dangerous". But I think one should apply
    any means and habits that avoid the errors that one personally knows
    to make.


    Sure.

    For collaborative work we therefore had a rule to always use braces.


    Good. And in collaborative work, compromises are often made - following
    the style of existing code will often overrule other style rules.


    I do the same, but restrict it to simpler statements.

    "Simpler" is a matter of taste and subjective judgement here -
    "return;", "break;", "continue;" are all "simple".˙ A short assignment
    is "simple".˙ For a longer printf, I'd usually use braces.˙ If the
    statement is too long to be comfortable on one line, or may reasonably
    become so in future modifications, then I'd have braces.

    For specific "simple statements" like early exits I usually even add
    an empty line after it;

    ˙˙˙ if (!precond)
    ˙˙˙˙˙˙˙ return special;

    ˙˙˙ regular_process;


    The empty line here helps, I think, and reduces some risk of error.


    For 'if'-cascades with "simple statements" I also omit the line-break, though. As you say it's also about any specific code being comfortably represented.

    Occasionally a repeating pattern in code is clearer if you your usual
    rules are set aside. Clarity is more important than consistency.


    Being a personal preference one should use a style to minimize problems
    in one's own style, or follow the company standards where collaborative
    work is expected.


    Yes.


    --- 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 15 09:41:40 2026
    On 2026-09-15 09:07, David Brown wrote:
    On 14/09/2026 23:56, Janis Papanagnou wrote:
    [...]

    I have the habit to regularly use a line-break and indentation here.

    ˙˙˙˙ if (retval)
    ˙˙˙˙˙˙˙˙ fprintf(stderr, "retval is %d\n", retval);


    To my eyes (and I fully appreciate that this kind of thing is highly subjective), that is the worst you can do.

    Yes, you said that before. (But your example below doesn't quite fit.)

    ˙That's how you end up with
    mistakes like this, after lines are added, removed or changed during
    code maintenance :

    Erm, no. - First, I never need to use 'goto' with my programming style.
    And second, a 'goto' I'd handle like a 'return' (as seen in my example
    below); any "severe disruption" of the linear processing I'd indicate
    by an empty line.


    ˙˙˙˙if (...)
    ˙˙˙˙˙˙˙ goto fail;
    ˙˙˙˙˙˙˙ goto fail;

    [...]


    For specific "simple statements" like early exits I usually even add
    an empty line after it;

    ˙˙˙˙ if (!precond)
    ˙˙˙˙˙˙˙˙ return special;

    ˙˙˙˙ regular_process;


    The empty line here helps, I think, and reduces some risk of error.

    It indeed does. (And certainly works for me.)

    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 15 10:22:56 2026
    On 15/09/2026 09:41, Janis Papanagnou wrote:
    On 2026-09-15 09:07, David Brown wrote:
    On 14/09/2026 23:56, Janis Papanagnou wrote:
    [...]

    I have the habit to regularly use a line-break and indentation here.

    ˙˙˙˙ if (retval)
    ˙˙˙˙˙˙˙˙ fprintf(stderr, "retval is %d\n", retval);


    To my eyes (and I fully appreciate that this kind of thing is highly
    subjective), that is the worst you can do.

    Yes, you said that before. (But your example below doesn't quite fit.)

    ˙That's how you end up with mistakes like this, after lines are added,
    removed or changed during code maintenance :

    Erm, no. - First, I never need to use 'goto' with my programming style.
    And second, a 'goto' I'd handle like a 'return' (as seen in my example below); any "severe disruption" of the linear processing I'd indicate
    by an empty line.

    The example was not about "goto" itself. It was paraphrased from the
    massive vulnerability "Heartbleed" in OpenSSL, where code that had been written in "your" style had later been edited had resulted in the code
    below. There were a series of "if (test...)" lines followed by "goto
    fail;" lines, in the format style you use. During a refactoring or
    change of these, one of the tests had been removed but by mistake the
    "goto fail;" line was not removed. This resulted in one of the biggest security failures seen.

    If the code had been written in /my/ style - either with the "goto
    fail;" on the same line, or with braces around it - it is extremely
    unlikely that the mistake could have happened, while still having code
    that could compile.

    Now, the mistake also required other failures - failure in code review, failure to test properly, failure to use static error checking (gcc's "-Wmisleading-indent" would have spotted it), and general failure of the
    IT world to put enough effort and resources into supporting such a
    critical piece of software. It is always thus when something like this happens - multiple safeguards must fail. A safe coding style - which
    this is not - would have been an additional safeguard. You can, of
    course, put different emphasis on different aspects of these safeguards
    - maybe you don't need any static error checking if you have good enough testing, and you don't need a good coding style if code reviews are
    careful enough. But I believe it always makes sense to make good use of
    the easy and cheap guards - basic static error checking and good coding
    style.

    Safe coding styles do not in any sense eliminate bugs or guarantee
    correct code, but they reduce the risk of certain classes of code bugs
    and code misunderstandings. Having a style where indentation sometimes
    means blocks, and sometimes does not, is a /bad/ idea for code safety
    because it increases the cognitive load to interpret the code.



    ˙˙˙˙˙if (...)
    ˙˙˙˙˙˙˙˙ goto fail;
    ˙˙˙˙˙˙˙˙ goto fail;

    [...]


    For specific "simple statements" like early exits I usually even add
    an empty line after it;

    ˙˙˙˙ if (!precond)
    ˙˙˙˙˙˙˙˙ return special;

    ˙˙˙˙ regular_process;


    The empty line here helps, I think, and reduces some risk of error.

    It indeed does. (And certainly works for me.)

    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 Tue Sep 15 11:51:26 2026
    On 2026-09-15 10:22, David Brown wrote:
    On 15/09/2026 09:41, Janis Papanagnou wrote:
    On 2026-09-15 09:07, David Brown wrote:
    On 14/09/2026 23:56, Janis Papanagnou wrote:
    [...]

    I have the habit to regularly use a line-break and indentation here.

    ˙˙˙˙ if (retval)
    ˙˙˙˙˙˙˙˙ fprintf(stderr, "retval is %d\n", retval);


    To my eyes (and I fully appreciate that this kind of thing is highly
    subjective), that is the worst you can do.

    Yes, you said that before. (But your example below doesn't quite fit.)

    ˙That's how you end up with mistakes like this, after lines are
    added, removed or changed during code maintenance :

    Erm, no. - First, I never need to use 'goto' with my programming style.
    And second, a 'goto' I'd handle like a 'return' (as seen in my example
    below); any "severe disruption" of the linear processing I'd indicate
    by an empty line.

    The example was not about "goto" itself.

    I'm well aware that your 'goto' example was badly chosen, and that
    there are other examples that illustrate your point more accurately.
    (But I was also aware what "problems" you actually have in mind; I
    know the mindset, there was actually no need to be that verbose. :-)

    [...] This resulted in one of the biggest security failures seen.

    Obviously a failure in two ways; having insufficient QA measures,
    and programmers that had problems with the necessary attention and
    experience.

    (Adding after I read your text below: Or maybe subjective problems
    with the "abstract picture" one has about the syntactic elements.)

    [...]

    Now, the mistake also required other failures - failure in code review, failure to test properly, failure to use static error checking (gcc's "- Wmisleading-indent" would have spotted it), and general failure of the
    IT world to put enough effort and resources into supporting such a
    critical piece of software.

    Yes.

    It is always thus when something like this
    happens - multiple safeguards must fail.˙ A safe coding style - which
    this is not - would have been an additional safeguard.˙ You can, of
    course, put different emphasis on different aspects of these safeguards
    - maybe you don't need any static error checking if you have good enough testing, and you don't need a good coding style if code reviews are
    careful enough.˙ But I believe it always makes sense to make good use of
    the easy and cheap guards - basic static error checking and good coding style.

    Right. - But don't forget that "spurious means" to tackle a topic is
    as well a source of obfuscating information; I certainly won't judge
    whether one or the other is in any (absolute or relative) way "better",
    but it certainly reminds me the recurring "if(a=5) vs. if(5=a)" debate
    to "ensure" "programming safety".


    Safe coding styles do not in any sense eliminate bugs or guarantee
    correct code, but they reduce the risk of certain classes of code bugs
    and code misunderstandings.

    Sure. - The point is; is there an objectively safe style here?
    I think there's subjective styles that helps some and annoys others.

    I don't think it makes sense to argue about that. (Especially given
    that we both have many decades of experience in the area.)

    Having a style where indentation sometimes
    means blocks, and sometimes does not, is a /bad/ idea for code safety because it increases the cognitive load to interpret the code.

    I disagree. - Your statement makes assumptions about a subjective idea
    of two different things. I can agree only insofar as accepting that you
    have that picture in mind, and with that picture it seems inconsistent
    (or something like that) to you. So I accept it's "cognitive load" for
    you. (While spurious syntax elements is "cognitive load" for me.)

    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 15 11:28:24 2026
    On 15/09/2026 02:48, Waldek Hebisch wrote:
    bart <bc@freeuk.com> wrote:

    I have a lot of experience of dynamic languages that ran at customer
    sites. Such language errors were extremely rare.

    It's not that I did extensive testing, but with normal development over
    a longish time-frame (eg. 1-2 years), you will uncover a lot of bugs!

    I would say that normally it is rare to discover such bugs. Simply
    your program happily runs for 20 years and then you suddenly discover
    that some strange but valid input causes a crash.

    Errors in a dynamic program would be trapped and reported, rather than
    cause a crash (unless it was a deeper within the implementation).

    Then that dynamic module would terminate, but the app was still running
    and the user could do something else.

    More common were bugs in the main native code app, and with that in
    mind, we had an auto-save feature to recover the user's data if those
    caused a crash, but they may have lost some minutes' work.

    (Funnily enough, one of my scripting language apps, which was a custom
    POS system, ran daily for at least 23 years, in an environment with
    frequent power cuts).)


    Let me mention that one of speed improvements is quite recent.
    I spent semething like 2-3 days to shorten real time of parallel
    build from about 60s to 45s (that involves more than compilation,
    so is longer than just compile time). Comparing the two things
    it seems that I will need about 5000 builds to recover time
    that I spent on speeding up the build. Given that I am doing
    some hundreds of builds per year,

    Per year? I could easily do hundreds of builds per day!

    Essentially my builds are instant, certainly for my projects of up to
    50Kloc where they finish within 0.1s. This is important for
    whole-program compilation where you can't choose to compile just one
    modified module.

    I think for me the costs of those language features - overloading
    functions and type inference, and what sounds like some kind of
    inheritance - would be just too high. I wouldn't have them, or would
    make compromises, or see if I could devise my own solutions.

    It sounds like you inherited your language.



    --- 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 15 12:53:38 2026
    On 15/09/2026 11:51, Janis Papanagnou wrote:
    On 2026-09-15 10:22, David Brown wrote:
    On 15/09/2026 09:41, Janis Papanagnou wrote:
    On 2026-09-15 09:07, David Brown wrote:
    On 14/09/2026 23:56, Janis Papanagnou wrote:
    [...]

    I have the habit to regularly use a line-break and indentation here. >>>>>
    ˙˙˙˙ if (retval)
    ˙˙˙˙˙˙˙˙ fprintf(stderr, "retval is %d\n", retval);


    To my eyes (and I fully appreciate that this kind of thing is highly
    subjective), that is the worst you can do.

    Yes, you said that before. (But your example below doesn't quite fit.)

    ˙That's how you end up with mistakes like this, after lines are
    added, removed or changed during code maintenance :

    Erm, no. - First, I never need to use 'goto' with my programming style.
    And second, a 'goto' I'd handle like a 'return' (as seen in my example
    below); any "severe disruption" of the linear processing I'd indicate
    by an empty line.

    The example was not about "goto" itself.

    I'm well aware that your 'goto' example was badly chosen, and that
    there are other examples that illustrate your point more accurately.
    (But I was also aware what "problems" you actually have in mind; I
    know the mindset, there was actually no need to be that verbose. :-)

    [...] This resulted in one of the biggest security failures seen.

    Obviously a failure in two ways; having insufficient QA measures,
    and programmers that had problems with the necessary attention and experience.

    (Adding after I read your text below: Or maybe subjective problems
    with the "abstract picture" one has about the syntactic elements.)

    [...]

    Now, the mistake also required other failures - failure in code
    review, failure to test properly, failure to use static error checking
    (gcc's "- Wmisleading-indent" would have spotted it), and general
    failure of the IT world to put enough effort and resources into
    supporting such a critical piece of software.

    Yes.

    It is always thus when something like this happens - multiple
    safeguards must fail.˙ A safe coding style - which this is not - would
    have been an additional safeguard.˙ You can, of course, put different
    emphasis on different aspects of these safeguards - maybe you don't
    need any static error checking if you have good enough testing, and
    you don't need a good coding style if code reviews are careful
    enough.˙ But I believe it always makes sense to make good use of the
    easy and cheap guards - basic static error checking and good coding
    style.

    Right. - But don't forget that "spurious means" to tackle a topic is
    as well a source of obfuscating information; I certainly won't judge
    whether one or the other is in any (absolute or relative) way "better",
    but it certainly reminds me the recurring "if(a=5) vs. if(5=a)" debate
    to "ensure" "programming safety".

    Fair point. It would be wrong to note that this particular bug would
    have been prevented by a particular coding practice, and use that to say
    that we should always follow that coding practice. One data point is
    not statistical evidence.

    And we all know we should be writing "if (a == 5)", with decent spacing :-)

    Far more effective than any one developer changing their coding style
    would be having more warnings enabled by default in common compilers.
    (clang warns about "if (a = 5)" by default, while gcc needs "-Wall".
    Both warn about the misleading indentation only when warnings are enabled.)



    Safe coding styles do not in any sense eliminate bugs or guarantee
    correct code, but they reduce the risk of certain classes of code bugs
    and code misunderstandings.

    Sure. - The point is; is there an objectively safe style here?
    I think there's subjective styles that helps some and annoys others.


    I have no statistics or reports to back up anything I say, so I can only
    say that I would /expect/ to see a small but measurable reduction in
    code errors if "indent without braces" conditionals are not allowed in
    code, if one were to compare code samples that had not used appropriate
    static checks. That is, I /believe/ there is a objective difference
    here. But I certainly can't claim to /know/ that there is. And even if statistics bear me out here (maybe some PhD student has done the
    research), that would still not contradict your statement. It is
    entirely reasonable to suppose that the style choices here would reduce
    risks for some programmers while making no difference to others - and no
    one likes being told to change their style without good reason.

    I don't think it makes sense to argue about that. (Especially given
    that we both have many decades of experience in the area.)


    This also makes it difficult to judge. I am confident that any choice
    of style here would make no difference to the risk of errors in either
    your code or my code - we both know how to use "-Wall" and pay attention
    to the warnings, so if we /did/ make a mistake, our tools would tell us.

    Having a style where indentation sometimes means blocks, and sometimes
    does not, is a /bad/ idea for code safety because it increases the
    cognitive load to interpret the code.

    I disagree. - Your statement makes assumptions about a subjective idea
    of two different things. I can agree only insofar as accepting that you
    have that picture in mind, and with that picture it seems inconsistent
    (or something like that) to you. So I accept it's "cognitive load" for
    you. (While spurious syntax elements is "cognitive load" for me.)


    Okay - again, that's a fair point. Cognitive load is always subjective,
    as it is less effort to interpret code written in a style with which the reader is most familiar.


    --- 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 15 14:54:17 2026
    bart <bc@freeuk.com> wrote:
    On 15/09/2026 02:48, Waldek Hebisch wrote:
    bart <bc@freeuk.com> wrote:

    I have a lot of experience of dynamic languages that ran at customer
    sites. Such language errors were extremely rare.

    It's not that I did extensive testing, but with normal development over
    a longish time-frame (eg. 1-2 years), you will uncover a lot of bugs!

    I would say that normally it is rare to discover such bugs. Simply
    your program happily runs for 20 years and then you suddenly discover
    that some strange but valid input causes a crash.

    Errors in a dynamic program would be trapped and reported, rather than
    cause a crash (unless it was a deeper within the implementation).

    Then that dynamic module would terminate, but the app was still running
    and the user could do something else.

    By crash I mean that program can not succesfully finish requested
    work. It is nice to avoid losing user data, but from user point
    of view there is still a crash.

    More common were bugs in the main native code app, and with that in
    mind, we had an auto-save feature to recover the user's data if those
    caused a crash, but they may have lost some minutes' work.

    (Funnily enough, one of my scripting language apps, which was a custom
    POS system, ran daily for at least 23 years, in an environment with
    frequent power cuts).)


    Let me mention that one of speed improvements is quite recent.
    I spent semething like 2-3 days to shorten real time of parallel
    build from about 60s to 45s (that involves more than compilation,
    so is longer than just compile time). Comparing the two things
    it seems that I will need about 5000 builds to recover time
    that I spent on speeding up the build. Given that I am doing
    some hundreds of builds per year,

    Per year? I could easily do hundreds of builds per day!

    Essentially my builds are instant, certainly for my projects of up to
    50Kloc where they finish within 0.1s. This is important for
    whole-program compilation where you can't choose to compile just one modified module.

    As I wrote, code is incrementally tested. Frequently new code
    is interactively tested outside of any module (that is pretty
    fast), when it works I change it into a module which is separately
    compiled. Only when new module or change to existing one passes
    test I do full build.

    Technically, with 45s per build I could do few hundreds build a
    day. But it is much more efficient to operate as above.

    In the past I was teaching programming in Turbo Pascal. I remember
    student pressing "compile" key after typing a few characters.
    This made some sense, compilation was essentially immediate and
    gave feedback, that is presence or absence of syntax errors. But
    I can enter somewhat bigger piece of code without making syntax
    error (I make a lot of silly errors, but not so much as to compile
    every few characters). And incremental compilation is reasonably
    fast. Also syntax error are much faster than succesful compilation.

    I think for me the costs of those language features - overloading
    functions and type inference, and what sounds like some kind of
    inheritance - would be just too high. I wouldn't have them, or would
    make compromises, or see if I could devise my own solutions.

    Faster compiler probably would speed up my work by few percent. Main
    gain probably would be that I could use slower computer. OTOH
    I would guesstimate that language features increase productivity
    by 50% or more.

    It sounds like you inherited your language.

    Yes.

    --
    Waldek Hebisch

    --- 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 15 21:56:04 2026
    On 15/09/2026 15:54, Waldek Hebisch wrote:
    bart <bc@freeuk.com> wrote:

    Technically, with 45s per build I could do few hundreds build a
    day.

    It would take up half your day!

    But it is much more efficient to operate as above.

    In the past I was teaching programming in Turbo Pascal. I remember
    student pressing "compile" key after typing a few characters.
    This made some sense, compilation was essentially immediate and
    gave feedback, that is presence or absence of syntax errors. But
    I can enter somewhat bigger piece of code without making syntax
    error (I make a lot of silly errors, but not so much as to compile
    every few characters). And incremental compilation is reasonably
    fast. Also syntax error are much faster than succesful compilation.

    Smart editors will now do doing parsing etc to give instant feedback and
    to automate code layout. A different parser from that of a compiler, to
    cope with incomplete code fragments.

    (I don't use a smart editor...)

    I think for me the costs of those language features - overloading
    functions and type inference, and what sounds like some kind of
    inheritance - would be just too high. I wouldn't have them, or would
    make compromises, or see if I could devise my own solutions.

    Faster compiler probably would speed up my work by few percent. Main
    gain probably would be that I could use slower computer. OTOH
    I would guesstimate that language features increase productivity
    by 50% or more.

    So you've adapted to what you have and learned how to work effectively
    with it.

    But suppose, somehow, a full build of your whole application could be
    done in zero time or near enough.

    You wouldn't need parallel processing. You wouldn't have to bother with incremental compilation. You wouldn't have to set up isolated tests in
    order to have smaller, faster-to-build programs.

    Your way of working would change.

    This is pretty much how it works with dynamic languages that are run
    from source. And some are using JIT methods on static languages
    (although tricky language features could still affect the front-end
    compiler).

    I think that is generally considered to be a productive approach.



    --- 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 15 21:34:50 2026
    bart <bc@freeuk.com> writes:
    On 15/09/2026 15:54, Waldek Hebisch wrote:
    bart <bc@freeuk.com> wrote:

    But suppose, somehow, a full build of your whole application could be
    done in zero time or near enough.


    Figure out how to build linux (a C application) in zero time and get back to us.


    --- 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 16 00:36:54 2026
    On 15/09/2026 22:34, Scott Lurndal wrote:
    bart <bc@freeuk.com> writes:
    On 15/09/2026 15:54, Waldek Hebisch wrote:
    bart <bc@freeuk.com> wrote:

    But suppose, somehow, a full build of your whole application could be
    done in zero time or near enough.


    Figure out how to build linux (a C application) in zero time and get back to us.


    WH's application is some 200K lines; something of that size would be
    feasible.

    Here for example is SQLite3 run from source:

    c:\cx>cc -i sql
    Compiling sql.c to sql.(int)
    SQLite version 3.25.3/MCC 2018-11-05 20:37:38
    Enter ".help" for usage hints.
    Connected to a transient in-memory database.
    Use ".open FILENAME" to reopen on a persistent database.
    sqlite>

    With -i (interpret) it takes 0.15 seconds to get from source to here.
    With -r (compile to native) it takes 0.25 seconds. This is a 250Kloc C
    program on a slow machine.

    However my remark was hypothetical: how would development habits change
    if that was the case?


    --- 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 16 02:21:41 2026
    bart <bc@freeuk.com> wrote:
    On 15/09/2026 15:54, Waldek Hebisch wrote:
    bart <bc@freeuk.com> wrote:

    Technically, with 45s per build I could do few hundreds build a
    day.

    It would take up half your day!

    One could do something useful during build. Or simply check for
    Usenet news.

    I think for me the costs of those language features - overloading
    functions and type inference, and what sounds like some kind of
    inheritance - would be just too high. I wouldn't have them, or would
    make compromises, or see if I could devise my own solutions.

    Faster compiler probably would speed up my work by few percent. Main
    gain probably would be that I could use slower computer. OTOH
    I would guesstimate that language features increase productivity
    by 50% or more.

    So you've adapted to what you have and learned how to work effectively
    with it.

    But suppose, somehow, a full build of your whole application could be
    done in zero time or near enough.

    You wouldn't need parallel processing. You wouldn't have to bother with incremental compilation. You wouldn't have to set up isolated tests in
    order to have smaller, faster-to-build programs.

    Your way of working would change.

    Probably not that much. Normally at any given time I work on a single
    module or a few. For me it is convenient to have all working files
    in a single directory. I do not want to clutter this directory with
    other files. So if system did not support incremental compilation
    I would probably need to emulate it so that compiling a single file
    would pick other sources from system directory.

    Also, you samewhat ignore testing. Significant point with incremental compilation is that my test state (date held in variables, helper
    functions) survive compilation of modified file, so I can immediately
    go back to testing.

    One more thing: there are also C sources in the system (about 50000
    lines). Currently C compilation is fast enough (and in paralle build
    partially overlaps with other things), but even if other code compiled
    in zero time, there still would be time taken by C compilation.

    This is pretty much how it works with dynamic languages that are run
    from source. And some are using JIT methods on static languages
    (although tricky language features could still affect the front-end compiler).

    My developement work mostly is like in dynamic language. Some
    modules need several seconds to compile, but most compile in a
    fraction of second. I see that compilation is not instanteous,
    but with exception of few offenders it is fast enough.

    I think that is generally considered to be a productive approach.

    Sure. AFAICS I have most benefits of working with dynamic
    language. Main difference is compile time type checking, which
    for me is a benefit (but many folks in dynamic camp dislike it).
    Also, I get adequate speed at runtime, unlike some systems that
    relay on interpretation. And runtime speed matters for developement,
    as some test cases need long time (image waiting 30 minutes to
    see effect of a bug).

    BTW. I also work with a different system, which is capable of compiling
    about 100000 (maybe more, there are include files and and it requires
    some effort to determine what exactly is compiled) lines per second in
    fastest mode. This does not change much how I work. Actually, one
    difference is that the second system is capable of compiling each
    function separately and I sometimes take advantage of this. Maybe
    bigger difference is that normally the second system compiles to memory.
    One can dump memory and reload later, but one can not do independent compilation in this way. So for smaller files I just keep them
    in source form, they are freashly compiled for each run. There is
    a different mode, which compiles to assembler which is assembled and
    linked in almost conventional way, but it is slower (closer to 30000
    lines per second). For this system build of core system takes about
    15 seconds (nontrivial part of which is indexing documentation). Note:
    this is serial build on a single core. There is also an extention
    providing image manipulation. This uses C file having few hundred
    lines, this file takes another 15 seconds to compile using GCC. But
    it is worth the time, GCC nicely vectorises the code considerably
    speeding up graphic operations.

    BTW2: I have pretty fast Modula-2 to C convertor. Theoretically
    I could couple it with Tiny C to get pretty fast Modula-2
    compiler. But in practice, for my use most of the time GCC is
    fast enough.

    --
    Waldek Hebisch

    --- 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 16 09:08:02 2026
    On 15/09/2026 22:56, bart wrote:

    So you've adapted to what you have and learned how to work effectively
    with it.


    You are forever trying to claim that this is somehow a bad thing.

    Most of us regulars here in comp.lang.c are not omnipotent, nor do we
    have unlimited time. We prefer to spend our time and effort on
    particular focused tasks - usually the tasks we get paid to do, or alternatively the tasks we enjoy doing.

    We cannot do /everything/ - there is not the time. I'm sure most of us,
    deep down, know that we could write a better C compiler than gcc or
    clang, and design a better language than C.

    But we don't have the time or inclination. We don't have the need. The
    tools that exist already do the job we need. We find convenient ways to
    make the whole process more efficient, and get on with the programming
    we actually want to do. (And we don't have to look far to find these
    methods - millions of developers use build systems and decent editors.
    We are not teenagers with a ZX Spectrum in our bedrooms, we are
    professionals who use professional tools.)

    What do you really want people here to do? Should we intentionally make
    our lives difficult by doing serial clean rebuilds all the time, and use
    MS Notepad as an editor, just so that we too can feel the pain and
    suffering you feel? Should we stop all our work, give up our jobs, and
    write our own C compilers? Should we spend have our life whining and
    moaning in Usenet groups and other online forums about how terrible C is
    and how bad compilers are, complaining to people who have no influence
    over any of it and can work fine with the language and tools?

    Or do you want us to bow down to you and exclaim our undying admiration
    for your language and compilers?

    I presume you are not interested in hearing that we too would be happy
    if compilers were faster, or that we too think that C has quirks,
    oddities, and aspects that we would prefer were different - if so, you'd
    have switched the broken record a couple of decades ago.

    So what would actually make you /happy/ here, and would let you change
    the subject?





    --- 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 16 11:21:29 2026
    On 16/09/2026 08:08, David Brown wrote:
    On 15/09/2026 22:56, bart wrote:

    So you've adapted to what you have and learned how to work effectively
    with it.


    You are forever trying to claim that this is somehow a bad thing.

    Most of us regulars here in comp.lang.c are not omnipotent, nor do we
    have unlimited time.˙ We prefer to spend our time and effort on
    particular focused tasks - usually the tasks we get paid to do, or alternatively the tasks we enjoy doing.

    We cannot do /everything/ - there is not the time.˙ I'm sure most of us, deep down, know that we could write a better C compiler than gcc or
    clang, and design a better language than C.

    But we don't have the time or inclination.˙ We don't have the need.˙ The tools that exist already do the job we need.˙ We find convenient ways to make the whole process more efficient, and get on with the programming
    we actually want to do.˙ (And we don't have to look far to find these methods - millions of developers use build systems and decent editors.
    We are not teenagers with a ZX Spectrum in our bedrooms, we are professionals who use professional tools.)

    What do you really want people here to do?˙ Should we intentionally make
    our lives difficult by doing serial clean rebuilds all the time, and use
    MS Notepad as an editor, just so that we too can feel the pain and
    suffering you feel?˙ Should we stop all our work, give up our jobs, and write our own C compilers?˙ Should we spend have our life whining and moaning in Usenet groups and other online forums about how terrible C is
    and how bad compilers are, complaining to people who have no influence
    over any of it and can work fine with the language and tools?

    Or do you want us to bow down to you and exclaim our undying admiration
    for your language and compilers?

    No. But you don't need actively dislike them either or be so patronising
    about them.

    My language is probably the nearest to C in this class and level of
    language, while also being very different in look and feel. It would be foolish to just dismiss it.


    I presume you are not interested in hearing that we too would be happy
    if compilers were faster, or that we too think that C has quirks,
    oddities, and aspects that we would prefer were different - if so, you'd have switched the broken record a couple of decades ago.

    So what would actually make you /happy/ here, and would let you change
    the subject?
    What I would like is for somebody to actually admit that there might be
    a problem instead of just brushing it under the carpet.

    What I would like is to know that there is somebody out there who is
    keeping on top of inefficiencies and checking that a simple task doesn't
    take an inordinate and disproportionate amount of resources to do.

    I'm not saying that /you/ should do it or most who post here. You are
    just the users who have to work with what's available, eg. by applying
    more hardware resources and more ingenuity.

    Even WH has said they have worked at improving the throughput of their
    tools (although that was not for C).

    The recent example of those SDL3 headers is a good one. Even without
    needing to change the C language, or have super-fast compilers for it,
    those headers are grossly inefficient.

    That is something that could be partly be tackled by the people who
    distribute the header files, but more could also be done by those who
    create the tools.

    For example:

    * There are 86 files/82K lines of headers, counted statically, but
    nearly 500 dynamic #includes are done, scanning or skipping over half a million lines of declarations

    * Yet they contain only about 4000 lines of actual information necessary
    to compile a program that uses that library. This is 1% of the lines
    that are scanned.

    * For a start, half the source is comments. Why are comments even needed
    for a header meant to be consumed by machine? There are surely separate
    docs! If they are for the SDL3 developers, then somebody using the
    library *is not the developer*!

    * There are thousands of /static/ conditional blocks (and a lot more encountered dynamically) all testing the same invariants over and over
    again.

    For example, once it is established that the compiler is not __MSCVER__,
    you don't need to test that (and to skip over blocks only relevant to
    that platform) 100 more times.

    So this could be done by recognising that a compact, streamlined API, dedicated to a particular platform (and maybe compiler) would be far better.

    But because that would mean many versions (more than the number of
    DLLs/.sos for different targets for example), this sounds like a
    compiler task.

    Most compilers already have an -E option to generate preprocessed source
    code. What is needed is say a -H option which does not discard
    information that a compiler still needs, if using an AOT-preprocessed
    header.

    Mostly this will be #defines. So it would not be too difficult. (Just
    tricky as SDL3 uses lots of #undefines too.)

    Maybe you don't think this is interesting or relevant or you think it is
    a waste of time. But if someone decided to add this to your favourite
    compiler I bet you would use it!

    In this case, it would reduce header code that needs to be processed
    /per module/, by some 99%, not 95%.

    Note that this is the same sort of principle as gcc's precompiled
    headers. But that doesn't simplify the headers at all; just
    pre-tokenises or something. The 3.6MB of SDL3 headers turn into one
    giant 30MB file. My approach would reduce them to one file of perhaps 0.2MB.


    --- 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 16 13:47:18 2026
    On 16/09/2026 12:21, bart wrote:
    On 16/09/2026 08:08, David Brown wrote:
    On 15/09/2026 22:56, bart wrote:

    So you've adapted to what you have and learned how to work
    effectively with it.


    You are forever trying to claim that this is somehow a bad thing.

    Most of us regulars here in comp.lang.c are not omnipotent, nor do we
    have unlimited time.˙ We prefer to spend our time and effort on
    particular focused tasks - usually the tasks we get paid to do, or
    alternatively the tasks we enjoy doing.

    We cannot do /everything/ - there is not the time.˙ I'm sure most of
    us, deep down, know that we could write a better C compiler than gcc
    or clang, and design a better language than C.

    But we don't have the time or inclination.˙ We don't have the need.
    The tools that exist already do the job we need.˙ We find convenient
    ways to make the whole process more efficient, and get on with the
    programming we actually want to do.˙ (And we don't have to look far to
    find these methods - millions of developers use build systems and
    decent editors. We are not teenagers with a ZX Spectrum in our
    bedrooms, we are professionals who use professional tools.)

    What do you really want people here to do?˙ Should we intentionally
    make our lives difficult by doing serial clean rebuilds all the time,
    and use MS Notepad as an editor, just so that we too can feel the pain
    and suffering you feel?˙ Should we stop all our work, give up our
    jobs, and write our own C compilers?˙ Should we spend have our life
    whining and moaning in Usenet groups and other online forums about how
    terrible C is and how bad compilers are, complaining to people who
    have no influence over any of it and can work fine with the language
    and tools?

    Or do you want us to bow down to you and exclaim our undying
    admiration for your language and compilers?

    No. But you don't need actively dislike them either or be so patronising about them.


    I am not dismissive about the language or tools - I have said many times
    that I think it is impressive that you've written a C compiler (however
    good, bad or indifferent it might be for anyone's uses), and the same
    about your languages.

    I am dismissive about your /claims/ based on these - your absurd
    comparisons to serious tools and real-world languages.

    My language is probably the nearest to C in this class and level of language, while also being very different in look and feel. It would be foolish to just dismiss it.


    It has no relevance in the world outside your bubble, so it is entirely reasonable to dismiss your language.

    If you had chosen a path of promoting your language and encouraging cooperation and collaboration, listening to feedback and working towards something that could be relevant to other people - then it would be a different matter. But you have chosen to assume that you, and you
    alone, can make the perfect language and perfect tools, and consider
    every other programmer, language designed and toolchain developer as
    amateurs incapable of making a decent language and tools. You chose to isolate yourself and your language, and to make it irrelevant.

    That is, of course, a choice you are free to make - and I am not in any
    way saying you made a bad choice here. You've had a successful career,
    and you have full control of your language - you do what you want with
    it, and don't have to consider anyone else or any knock-on effects when changing things. You can be justifiably proud of your achievements.

    The only thing you don't get to do is complain when no one takes your
    language seriously or considers it relevant to anyone else.


    I presume you are not interested in hearing that we too would be happy
    if compilers were faster, or that we too think that C has quirks,
    oddities, and aspects that we would prefer were different - if so,
    you'd have switched the broken record a couple of decades ago.

    So what would actually make you /happy/ here, and would let you change
    the subject?
    What I would like is for somebody to actually admit that there might be
    a problem instead of just brushing it under the carpet.


    But we don't have a problem. We have the C language, and C compilers.
    And it's a good (not perfect) language for a lot of uses, with good (not perfect) tools. Programmers should use that language and tools where
    they are suitable, and different languages and tools where those are
    better choices. And the language and tools improve over time.

    What I would like is to know that there is somebody out there who is
    keeping on top of inefficiencies and checking that a simple task doesn't take an inordinate and disproportionate amount of resources to do.


    Why?

    What makes you think that toolchain vendors do not consider time and
    resource uses as a factor in their development?

    What makes you think that anyone in this Usenet group could do anything
    about it if we agreed with you?

    I'm not saying that /you/ should do it or most who post here. You are
    just the users who have to work with what's available, eg. by applying
    more hardware resources and more ingenuity.


    Note that this "ingenuity" - using a build system - has been considered standard practice for software development for perhaps half a century or
    more.

    Even WH has said they have worked at improving the throughput of their
    tools (although that was not for C).


    There are plenty of situations where tools take significant time, and improving their speed is very much a priority (whether it is by
    improving the tools, or using faster hosts). C compilation is not one
    of those situations, for the vast majority of projects. Even for fairly
    big projects, such as the Linux kernel, the C compilation is only one
    part of the built time.

    The closest case is C++ compilation - big C++ projects can take a very
    long time to build. That is why the effort spent by clang, gcc and MSVC
    on improvement of build times is primarily for C++ and for link-time optimisation.

    Outside that, other tools such as simulations, testing, and serious code analysers can take a very long time to run.

    The recent example of those SDL3 headers is a good one. Even without
    needing to change the C language, or have super-fast compilers for it,
    those headers are grossly inefficient.

    So what?

    I did the timings there. The savings achievable from "instant" headers
    would be tiny fractions of a second. I have not used SDL, and don't
    know anything about their development processes, but I am confident that
    most SDL users would rather the SDL developers prioritised features and run-time efficiency of the resulting binaries rather than saving 0.1
    seconds per build.

    You are utterly obsessed with something that is utterly irrelevant in
    most cases (again, we are talking about C).


    Maybe you don't think this is interesting or relevant or you think it is
    a waste of time. But if someone decided to add this to your favourite compiler I bet you would use it!

    If I wanted to compile SDL code on my host, I'd use the SDL headers and
    the compiler on the host. If later versions of those SDL headers were re-organised for faster compiles, I'd use them if and when I updated the headers. I would not notice the saved milliseconds, but of course I
    would be using them.

    Would I use a compiler that has special fast-path handling of headers to
    skip extra includes, quickly discard unused code between "#if ...
    #endif" sets, and skim comments efficiently? Yes, I would use such a
    compiler - gcc has done so since very early versions, and I expect all
    other serious compilers do so too.


    In this case, it would reduce header code that needs to be processed /
    per module/, by some 99%, not 95%.

    Note that this is the same sort of principle as gcc's precompiled
    headers. But that doesn't simplify the headers at all; just pre-
    tokenises or something. The 3.6MB of SDL3 headers turn into one giant
    30MB file. My approach would reduce them to one file of perhaps 0.2MB.


    Your approach would make no difference to me (assuming I used SDL). I
    would not expect it to make a noticeable difference to anyone else doing
    real development work with the SDL libraries.

    There's a reason almost no one uses precompiled headers with C - it is
    rare that pure C projects have build times that are inconveniently long
    for development, and rarer still that this is because of headers.



    --- 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 16 13:16:08 2026
    bart <bc@freeuk.com> wrote:
    On 16/09/2026 08:08, David Brown wrote:
    On 15/09/2026 22:56, bart wrote:

    The recent example of those SDL3 headers is a good one. Even without
    needing to change the C language, or have super-fast compilers for it,
    those headers are grossly inefficient.

    That is something that could be partly be tackled by the people who distribute the header files, but more could also be done by those who
    create the tools.

    For example:

    * There are 86 files/82K lines of headers, counted statically, but
    nearly 500 dynamic #includes are done, scanning or skipping over half a million lines of declarations

    Do SDL3 use include guards? The expected convention is that header
    looks like:

    #ifndef XXXXXX
    #define XXXXXX
    ...
    #endif

    with possibly some trivial variation. That first non-comment thing
    in a header is a test and the whole body is inside a conditional.

    Assuming that SDL3 is doing this (and if not you should complain to
    them), then your compiler could recognize this pattern and skip
    the header when it is included second time. For this you need to
    recognize when two paths lead to the same file, recognize the test
    and check that test is indeed false when doing second include.

    Some headers may be intentionally included multiple times, but
    with include guards you should be able to include most files just
    once. IIUC both GCC and TCC handle this.

    * Yet they contain only about 4000 lines of actual information necessary
    to compile a program that uses that library. This is 1% of the lines
    that are scanned.

    * For a start, half the source is comments. Why are comments even needed
    for a header meant to be consumed by machine? There are surely separate docs! If they are for the SDL3 developers, then somebody using the
    library *is not the developer*!

    If you are developing an application you sometimes need to look
    at content of the headers. Comments presumably make it easier to
    understand the headers. Concerning documentation, this is derived
    thing, which hopefully agrees with the sources, but actual source
    is the ultimate truth and looking at source is more reliable (even if
    harder) than looking at documentation.

    * There are thousands of /static/ conditional blocks (and a lot more encountered dynamically) all testing the same invariants over and over again.

    For example, once it is established that the compiler is not __MSCVER__,
    you don't need to test that (and to skip over blocks only relevant to
    that platform) 100 more times.

    So this could be done by recognising that a compact, streamlined API, dedicated to a particular platform (and maybe compiler) would be far better.

    But because that would mean many versions (more than the number of
    DLLs/.sos for different targets for example), this sounds like a
    compiler task.

    I guess that smart compiler could create streamlined version of headers.
    That could be done when istalling the library. Or maybe the compiler
    could have a cache of streamline versions and use cached result
    when it is newer than library headers. As saying goes, this is
    small matter of programming. So somebody needs to implement it.
    And take into account that this should work without need of cooperation
    of all involved parties. Namely, if one compiler implement needed
    features, there is no warranty that other will do the same. And
    without support in all compilers library authors normally would
    write code for the lowest common denominator, that is assume no
    special support (and the same for packagers). You can not expect
    special action from users, most of them will just do what they
    learned as "standard commands" and "let computer do the rest"
    regardless how much CPU time it takes.

    Most compilers already have an -E option to generate preprocessed source code. What is needed is say a -H option which does not discard
    information that a compiler still needs, if using an AOT-preprocessed header.

    Mostly this will be #defines. So it would not be too difficult. (Just
    tricky as SDL3 uses lots of #undefines too.)

    Combine '#undefine' with conditionals unknown at preprocessing time
    and the problem becomes more interesting. IIUC developers of major
    comilers gave up at this point.

    Maybe you don't think this is interesting or relevant or you think it is
    a waste of time. But if someone decided to add this to your favourite compiler I bet you would use it!

    In this case, it would reduce header code that needs to be processed
    /per module/, by some 99%, not 95%.

    Note that this is the same sort of principle as gcc's precompiled
    headers. But that doesn't simplify the headers at all; just
    pre-tokenises or something. The 3.6MB of SDL3 headers turn into one
    giant 30MB file. My approach would reduce them to one file of perhaps 0.2MB.

    IIUC GCC precompiled header is simplified quite a lot, for example
    all preprocessor conditonals are removed and replaced by resulting
    expansion. Size may be just consequence of how this works. IIUC
    GCC just dump memory containing internal representation of content
    if the header. Given that modern machines have high memory bandwidth,
    loading it is pretty efficient.

    You mentioned 4000 nontivial lines, which probably means 4000 declarations. Internally GCC represents this as tree nodes and rather conservative
    estimate is that GCC needs 3 nodes per declaration. GCC tree nodes
    need probably about 100 bytes each (they contain several pointers),
    so that alone would imply about 1MB.

    GCC now prints rather detailed information about includes when printing
    error messages, so there must be enough additional information
    to track back result of expansion to the sources. And given that
    GCC uses memory dump, it is likely to contain some unneded garbage.

    At first glance 30 MB looks like a lot, but in advanced compiler
    you need a lot of information. And there is always a compromise:
    storing info means that it is "immediately" available, recomputing
    means that you can avoid memory acceses (which are expensive if
    you miss the cache). IIUC a lot of effort of GCC developers went
    into recomputing what can be cheaply recomputed, using packed
    representations and discarding not needed information. But
    a lot needs to be stored to avoid making GCC slower than it is.
    And the dump approach was chosen as the fastest one.

    --
    Waldek Hebisch

    --- 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 16 15:20:52 2026
    On 16/09/2026 12:47, David Brown wrote:
    On 16/09/2026 12:21, bart wrote:

    The recent example of those SDL3 headers is a good one. Even without
    needing to change the C language, or have super-fast compilers for it,
    those headers are grossly inefficient.

    So what?

    I did the timings there.˙ The savings achievable from "instant" headers would be tiny fractions of a second.

    I don't really trust your figures. I've today done a mock-up of a
    streamlined header for SDL3.

    In this form it is a file of just over 6K lines (probably there's stuff
    that doesn't need to be there, but it will suffice for this test).

    So here are my figures for a single 'hello-world' test for SDL3:

    sdl.h newsdl.h (normal vs compact)
    gcc 0.88 seconds 0.34 seconds
    gcc 0.24 seconds 0.22 seconds (using precompiled headers)
    bcc 0.17 seconds 0.04 seconds

    gcc 0.4 seconds 0.08 seconds (Linux/real time)

    And this is the test for 50 files each including one of those headers:

    sdl.h newsdl.h (normal vs compact)
    gcc 38 seconds 6 seconds (gcc *.c)
    bcc 8 seconds 1.7 seconds (bcc needs 50 invocations)

    That looks quite worthwhile to me. Another advantage is that the header
    is a single file that is easy to use, copy, bundle etc. You don't need
    -I options.

    You are utterly obsessed with something that is utterly irrelevant in
    most cases (again, we are talking about C).

    Let me ask you: how big, bloated and inefficient does such a header need
    to be for you to think there is a problem? How much does it need to slow
    down the build process?

    Or would you invest in a server farm first before you will admit there
    is a problem? Or is that only before you will admit it to me?

    Here are some file sizes:

    SDL3\*.h 3.6 MB
    SDL3.dll 5.4 MB
    newsdl.h 0.3 MB
    sdl.h.gch 30.4 MB
    newsdl.h.gch 7.2 MB
    sdl.m 0.17MB

    The DLL contains all the code to do all the work. The headers should
    only define the interface, and yet they're nearly as big as the library itself!

    With these figures, performance is on a par with using gcc's precompiled headers, for this project.

    However, my newsdl.h file could be used for multiple compilers on
    Windows. And it is 100 times smaller than that main .gch file.

    (That last file is what my conversion tool produces from the same 3.6MB, converting to bindings in my language. I don't know what unnecessary
    crap is still within newsdl.h. Today was just a proof of concept.)



    --- 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 16 15:26:14 2026
    On 16/09/2026 14:16, Waldek Hebisch wrote:
    bart <bc@freeuk.com> wrote:
    On 16/09/2026 08:08, David Brown wrote:
    On 15/09/2026 22:56, bart wrote:

    The recent example of those SDL3 headers is a good one. Even without
    needing to change the C language, or have super-fast compilers for it,
    those headers are grossly inefficient.

    That is something that could be partly be tackled by the people who
    distribute the header files, but more could also be done by those who
    create the tools.

    For example:

    * There are 86 files/82K lines of headers, counted statically, but
    nearly 500 dynamic #includes are done, scanning or skipping over half a
    million lines of declarations

    Do SDL3 use include guards? The expected convention is that header
    looks like:

    #ifndef XXXXXX
    #define XXXXXX
    ...
    #endif

    with possibly some trivial variation. That first non-comment thing
    in a header is a test and the whole body is inside a conditional.

    Guards are used, but conditional must still be skipped, not that simple
    as a closing '#endif' for example must match, or some could be inside comments.


    Assuming that SDL3 is doing this (and if not you should complain to
    them), then your compiler could recognize this pattern and skip
    the header when it is included second time. For this you need to
    recognize when two paths lead to the same file, recognize the test
    and check that test is indeed false when doing second include.

    Some headers may be intentionally included multiple times, but
    with include guards you should be able to include most files just
    once. IIUC both GCC and TCC handle this.

    * Yet they contain only about 4000 lines of actual information necessary
    to compile a program that uses that library. This is 1% of the lines
    that are scanned.

    * For a start, half the source is comments. Why are comments even needed
    for a header meant to be consumed by machine? There are surely separate
    docs! If they are for the SDL3 developers, then somebody using the
    library *is not the developer*!

    If you are developing an application you sometimes need to look
    at content of the headers. Comments presumably make it easier to
    understand the headers. Concerning documentation, this is derived
    thing, which hopefully agrees with the sources, but actual source
    is the ultimate truth and looking at source is more reliable (even if
    harder) than looking at documentation.

    * There are thousands of /static/ conditional blocks (and a lot more
    encountered dynamically) all testing the same invariants over and over
    again.

    For example, once it is established that the compiler is not __MSCVER__,
    you don't need to test that (and to skip over blocks only relevant to
    that platform) 100 more times.

    So this could be done by recognising that a compact, streamlined API,
    dedicated to a particular platform (and maybe compiler) would be far better. >>
    But because that would mean many versions (more than the number of
    DLLs/.sos for different targets for example), this sounds like a
    compiler task.

    I guess that smart compiler could create streamlined version of headers.
    That could be done when istalling the library. Or maybe the compiler
    could have a cache of streamline versions and use cached result
    when it is newer than library headers. As saying goes, this is
    small matter of programming. So somebody needs to implement it.
    And take into account that this should work without need of cooperation
    of all involved parties. Namely, if one compiler implement needed
    features, there is no warranty that other will do the same. And
    without support in all compilers library authors normally would
    write code for the lowest common denominator, that is assume no
    special support (and the same for packagers). You can not expect
    special action from users, most of them will just do what they
    learned as "standard commands" and "let computer do the rest"
    regardless how much CPU time it takes.

    Most compilers already have an -E option to generate preprocessed source
    code. What is needed is say a -H option which does not discard
    information that a compiler still needs, if using an AOT-preprocessed
    header.

    Mostly this will be #defines. So it would not be too difficult. (Just
    tricky as SDL3 uses lots of #undefines too.)

    Combine '#undefine' with conditionals unknown at preprocessing time
    and the problem becomes more interesting. IIUC developers of major
    comilers gave up at this point.

    Maybe you don't think this is interesting or relevant or you think it is
    a waste of time. But if someone decided to add this to your favourite
    compiler I bet you would use it!

    In this case, it would reduce header code that needs to be processed
    /per module/, by some 99%, not 95%.

    Note that this is the same sort of principle as gcc's precompiled
    headers. But that doesn't simplify the headers at all; just
    pre-tokenises or something. The 3.6MB of SDL3 headers turn into one
    giant 30MB file. My approach would reduce them to one file of perhaps 0.2MB.

    IIUC GCC precompiled header is simplified quite a lot, for example
    all preprocessor conditonals are removed and replaced by resulting
    expansion. Size may be just consequence of how this works. IIUC
    GCC just dump memory containing internal representation of content
    if the header. Given that modern machines have high memory bandwidth, loading it is pretty efficient.

    You mentioned 4000 nontivial lines, which probably means 4000 declarations. Internally GCC represents this as tree nodes and rather conservative
    estimate is that GCC needs 3 nodes per declaration. GCC tree nodes
    need probably about 100 bytes each (they contain several pointers),
    so that alone would imply about 1MB.

    GCC now prints rather detailed information about includes when printing
    error messages, so there must be enough additional information
    to track back result of expansion to the sources. And given that
    GCC uses memory dump, it is likely to contain some unneded garbage.

    At first glance 30 MB looks like a lot, but in advanced compiler
    you need a lot of information. And there is always a compromise:
    storing info means that it is "immediately" available, recomputing
    means that you can avoid memory acceses (which are expensive if
    you miss the cache). IIUC a lot of effort of GCC developers went
    into recomputing what can be cheaply recomputed, using packed
    representations and discarding not needed information. But
    a lot needs to be stored to avoid making GCC slower than it is.
    And the dump approach was chosen as the fastest one.

    See my post of a few minutes ago where I give the results of my experiments.





    --- 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 16 17:53:47 2026
    On 16/09/2026 16:20, bart wrote:
    On 16/09/2026 12:47, David Brown wrote:
    On 16/09/2026 12:21, bart wrote:

    The recent example of those SDL3 headers is a good one. Even without
    needing to change the C language, or have super-fast compilers for
    it, those headers are grossly inefficient.

    So what?

    I did the timings there.˙ The savings achievable from "instant"
    headers would be tiny fractions of a second.

    I don't really trust your figures. I've today done a mock-up of a streamlined header for SDL3.

    You are using an older computer, an old version of an inappropriate OS (Windows has its strengths, good points and good uses - this is not one
    of them), and have consistently shown you have trouble getting toolchain installations to work. So I don't trust your numbers to be a realistic reflection of real-world timings for other developers. I /do/ trust
    that the numbers you post are the numbers that /you/ measured on /your/ system, however. You should similarly believe the numbers I give, even
    if you think that most people using SDL will have setups more like your
    own one.


    In this form it is a file of just over 6K lines (probably there's stuff
    that doesn't need to be there, but it will suffice for this test).

    So here are my figures for a single 'hello-world' test for SDL3:

    ˙˙˙˙˙˙˙˙ sdl.h˙˙˙˙˙˙˙˙˙˙˙ newsdl.h˙˙˙˙˙˙ (normal vs compact)
    gcc˙˙˙˙˙ 0.88 seconds˙˙˙˙ 0.34 seconds
    gcc˙˙˙˙˙ 0.24 seconds˙˙˙˙ 0.22 seconds˙˙ (using precompiled headers)
    bcc˙˙˙˙˙ 0.17 seconds˙˙˙˙ 0.04 seconds

    gcc˙˙˙˙˙ 0.4˙ seconds˙˙˙˙ 0.08 seconds˙˙ (Linux/real time)

    And this is the test for 50 files each including one of those headers:

    ˙˙˙˙˙˙˙˙ sdl.h˙˙˙˙˙˙˙˙˙˙ newsdl.h˙˙˙˙˙˙˙ (normal vs compact)
    gcc˙˙˙˙˙ 38 seconds˙˙˙˙˙ 6˙˙ seconds˙˙˙˙ (gcc *.c)
    bcc˙˙˙˙˙˙ 8 seconds˙˙˙˙˙ 1.7 seconds˙˙˙˙ (bcc needs 50 invocations)

    That looks quite worthwhile to me.

    I can certainly agree that it is faster. But I am far from convinced
    that it is worthwhile.

    A rational developer working on an SDL project in C of any reasonable
    size is likely to be using gcc on Linux, and not be using precompiled
    headers. They will also use "make" (or another build system) and will,
    for most re-builds during development, have more cores than the number
    of files that need to be re-compiled. So the only figure that counts is
    the 0.4 vs 0.08 timing. They can expect, on average, to save 0.3
    seconds on their builds.

    Is it worth the SDL maintainers making a compact header, and being sure
    that it is always in sync? They could write automated tools to generate
    it, but it would be extra work, restrict what they can reasonably put in headers (to fit with their generator program), risk subtle problems, and
    mean that different people will use different sets of headers. No, it
    is not worth it.

    I don't have SDL3 - I have only looked at SDL2 headers, because I happen
    to have them on my system. I note that there are 26778 lines of code in
    the 78 header files, when comments and blank lines are omitted. That's
    a lot more than your 6K lines. I can't say if that is purely from pre-processor lines (which "cloc" counts, but you may have removed), or differences between SDL2 and SDL3.

    Another advantage is that the header
    is a single file that is easy to use, copy, bundle etc. You don't need -
    I options.

    My test file contained a single line :

    #include <SDL2/SDL.h>

    and compiled with

    gcc -c test.c

    There are no -I options.

    Single header files are not particularly exciting for a library like
    this. They can be useful for some libraries, especially if no
    additional source files are needed (that's more a C++ thing than a C
    thing). But when I am also getting manual pages, shared library files,
    etc., with a single "apt install libsdl2-dev" or click in a graphical
    package manager, there's no significant advantage to single headers.

    But I do like that from an IDE, I can easily navigate into headers and
    see the real header file, along with information and brief
    documentation. (I don't know or care how nice this is in SDL, as I
    don't use it.) It is easier to navigate multiple small headers than one
    huge one (within reason, of course), and it is better to have at least
    some information in these headers.

    I realise you like single compact files. That's fair enough - your preferences are your own. Don't make the mistake of assuming they apply
    to everyone else.


    You are utterly obsessed with something that is utterly irrelevant in
    most cases (again, we are talking about C).

    Let me ask you: how big, bloated and inefficient does such a header need
    to be for you to think there is a problem? How much does it need to slow down the build process?

    I've yet to use anything remotely too big. So any attempt at giving a
    number would be completely artificial.


    Or would you invest in a server farm first before you will admit there
    is a problem? Or is that only before you will admit it to me?

    I have not found header sizes in C to be a problem, at any time. I
    haven't used SDL, but if I choose to do so, I do not expect the header
    sizes to be a problem. So without a problem, there is nothing to "admit".

    And if I do, one day, find a set of headers that I need to use and which
    I felt made my work slower and less productive, then I most certainly
    would find a solution that does not involve decades of whinging in a newsgroup. I can't say what the right solution would be without seeing
    a problem, but certainly a faster host would be a feasible option. (Distributed compilation is sometimes used for big C++ projects.)

    We do, in fact, have a build server at my office. It's just a mini-PC
    with a nice AMD multi-core laptop processor and 64 GB ram. It is used
    for building embedded Linux setups and kernels, because those builds
    take quite a while on some of the other developer's desktops. The
    headers are not an issue - the main inconvenience is the many
    bottlenecks of configuration scripts rather than the actual compiles.



    --- 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 16 15:58:16 2026
    bart <bc@freeuk.com> wrote:
    On 16/09/2026 14:16, Waldek Hebisch wrote:
    bart <bc@freeuk.com> wrote:
    On 16/09/2026 08:08, David Brown wrote:
    On 15/09/2026 22:56, bart wrote:

    The recent example of those SDL3 headers is a good one. Even without
    needing to change the C language, or have super-fast compilers for it,
    those headers are grossly inefficient.

    That is something that could be partly be tackled by the people who
    distribute the header files, but more could also be done by those who
    create the tools.

    For example:

    * There are 86 files/82K lines of headers, counted statically, but
    nearly 500 dynamic #includes are done, scanning or skipping over half a
    million lines of declarations

    Do SDL3 use include guards? The expected convention is that header
    looks like:

    #ifndef XXXXXX
    #define XXXXXX
    ...
    #endif

    with possibly some trivial variation. That first non-comment thing
    in a header is a test and the whole body is inside a conditional.

    Guards are used, but conditional must still be skipped, not that simple
    as a closing '#endif' for example must match, or some could be inside comments.

    Of course you need to parse the file at least one time. But once
    you parsed file once and checked that it has correct include guard
    you mark it as having the guard and store test expression.
    Next time when the same file is included you just look in compiler
    tables and see that file has include guard. Then you verify the test condition. If everthing is OK (as it should be) you can skip
    the file on second and subsequent readings. According to your
    data instead of reading and parsing 0.5M lines you can limit
    this to 82K lines. Maybe not as good as your "compressed"
    header idea, but this works transparently with existing C sources.

    Note: above the assumption is that file did not change between
    two times when you should read it. I think that this is reasonable
    assumption. IIUC C standard leaves specific properties there
    to the implementation and given variation in compiler speed
    I do not think that anyone can usefuly modify headers during
    compilation. With assumption that header was not modified,
    the matching '#endif' must be in the same place as during
    first reading.

    Assuming that SDL3 is doing this (and if not you should complain to
    them), then your compiler could recognize this pattern and skip
    the header when it is included second time. For this you need to
    recognize when two paths lead to the same file, recognize the test
    and check that test is indeed false when doing second include.

    --
    Waldek Hebisch

    --- 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 16 17:33:17 2026
    bart <bc@freeuk.com> writes:
    On 16/09/2026 12:47, David Brown wrote:
    On 16/09/2026 12:21, bart wrote:

    The recent example of those SDL3 headers is a good one. Even without
    needing to change the C language, or have super-fast compilers for it,
    those headers are grossly inefficient.

    So what?

    I did the timings there.˙ The savings achievable from "instant" headers
    would be tiny fractions of a second.

    I don't really trust your figures. I've today done a mock-up of a >streamlined header for SDL3.

    In this form it is a file of just over 6K lines (probably there's stuff
    that doesn't need to be there, but it will suffice for this test).

    So here are my figures for a single 'hello-world' test for SDL3:

    sdl.h newsdl.h (normal vs compact)
    gcc 0.88 seconds 0.34 seconds

    That seems to be "tiny fractions of a second" to me. Pointless
    optimization for no appreciable return, almost in the noise.


    --- 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 16 19:13:23 2026
    On 16/09/2026 16:58, Waldek Hebisch wrote:
    bart <bc@freeuk.com> wrote:
    On 16/09/2026 14:16, Waldek Hebisch wrote:
    bart <bc@freeuk.com> wrote:
    On 16/09/2026 08:08, David Brown wrote:
    On 15/09/2026 22:56, bart wrote:

    The recent example of those SDL3 headers is a good one. Even without
    needing to change the C language, or have super-fast compilers for it, >>>> those headers are grossly inefficient.

    That is something that could be partly be tackled by the people who
    distribute the header files, but more could also be done by those who
    create the tools.

    For example:

    * There are 86 files/82K lines of headers, counted statically, but
    nearly 500 dynamic #includes are done, scanning or skipping over half a >>>> million lines of declarations

    Do SDL3 use include guards? The expected convention is that header
    looks like:

    #ifndef XXXXXX
    #define XXXXXX
    ...
    #endif

    with possibly some trivial variation. That first non-comment thing
    in a header is a test and the whole body is inside a conditional.

    Guards are used, but conditional must still be skipped, not that simple
    as a closing '#endif' for example must match, or some could be inside
    comments.

    Of course you need to parse the file at least one time. But once
    you parsed file once and checked that it has correct include guard

    An include guard looks the same as any other conditional block. There
    may be dozens in the same file.

    So here some analysis that a guard, which may have comments before and
    after, has a particular pattern and applies to the whole file.

    In any case, my stats show that 400K lines are still part of normal processing, while 150K lines are skipped due to false conditional blocks.

    This is despite those guards being everywhere. Here's an include
    structure for one header, 'sdl_init.h', which is one of a list of 60
    includes in stl.h:

    #include sdl.h
    #include sdl_init.h
    #include sdl_stdinc.h
    #include sdl_platform_defines.h
    #include sdl_begin_code.h
    #include sdl_close_code.h
    #include sdl_error.h
    #include sdl_stdinc.h
    #include sdl_begin_code.h
    #include sdl_close_code.h
    #include sdl_events.h
    #include sdl_stdinc.h
    #include sdl_audio.h
    #include sdl_stdinc.h
    #include sdl_endian.h
    #include sdl_stdinc.h
    ...
    #include sdl_error.h
    #include sdl_mutex.h
    #include sdl_properties.h
    #include sdl_iostream.h
    13 more includes within sdl_events
    #include sdl_begin_code.h
    #include sdl_close_code.h

    I haven't bothered expanding all of them, and haven't included non-SDL headers.

    Every one of those has a guard. So, does that mean that the body of 'SDL_stdinc.h' for example should only ever be encountered once?

    I tested this by inserting a function body just after the guard of stl_stdinc.h. First I wrote it twice, to ensure it generated an error.

    Then I went back to one definition. This was fine, so the guards work.
    In that case, what the hell is it spending 400000 lines processing?!

    Some more investigation is needed via special tracking info added to my compiler. I will update this later.


    But in the meantime, just look at that tree: this is just for one top level-header, and is not even fully expanded. It's horrible mess, and
    that's without develving into the contents.

    Even if the library needs to be split into 60-80 parts for development reasons, this is over the top. And the user is still is not interested
    in those 60 parts, just the one library called 'SDL'.

    The headers actually define these entities (figures approx, derived from
    the tool that generates my bindings):

    1300 Functions (1050 functions and 250 procedures
    350 Named constants (defined from #defines)
    1100 Enumerations
    260 Struct definitions

    There's another stuff, like typedefs, and 15 actual function
    definitions. But the above is 3000 lines at one per line (plus some 1000
    more lines for struct fields).

    If I look at SDL3.DLL, it exports exactly 1270 functions, and no variables.

    Clearly all that's needed are signatures for those functions, plus any typedefs, structs, #defines and enums that are used. Exactly what my
    tool extracts.


    Assuming that SDL3 is doing this (and if not you should complain to
    them), then your compiler could recognize this pattern and skip
    the header when it is included second time. For this you need to
    recognize when two paths lead to the same file, recognize the test
    and check that test is indeed false when doing second include.



    --- 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 16 19:19:34 2026
    On 16/09/2026 18:33, Scott Lurndal wrote:
    bart <bc@freeuk.com> writes:
    On 16/09/2026 12:47, David Brown wrote:
    On 16/09/2026 12:21, bart wrote:

    The recent example of those SDL3 headers is a good one. Even without
    needing to change the C language, or have super-fast compilers for it, >>>> those headers are grossly inefficient.

    So what?

    I did the timings there.˙ The savings achievable from "instant" headers
    would be tiny fractions of a second.

    I don't really trust your figures. I've today done a mock-up of a
    streamlined header for SDL3.

    In this form it is a file of just over 6K lines (probably there's stuff
    that doesn't need to be there, but it will suffice for this test).

    So here are my figures for a single 'hello-world' test for SDL3:

    sdl.h newsdl.h (normal vs compact)
    gcc 0.88 seconds 0.34 seconds

    That seems to be "tiny fractions of a second" to me. Pointless
    optimization for no appreciable return, almost in the noise.


    This is for *one* C source file that contains little more than that
    header. Typically there are multiple source files containing code of
    their own that need compiling, and which might need there own header.

    This is spending the best part of a second compiling 1300 function
    signatures; this is 1980s machine speed.

    You seem to be involved in developing new, higher performance
    processors, and yet you're happy to all see all that power wasted
    because people who write these bloated messes of code are so fucking lazy.


    --- 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 16 18:30:06 2026
    bart <bc@freeuk.com> writes:
    On 16/09/2026 16:58, Waldek Hebisch wrote:
    bart <bc@freeuk.com> wrote:
    <snip>

    Every one of those has a guard. So, does that mean that the body of >'SDL_stdinc.h' for example should only ever be encountered once?


    Cf. #pragma once


    --- 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 16 18:34:20 2026
    bart <bc@freeuk.com> writes:
    On 16/09/2026 18:33, Scott Lurndal wrote:
    bart <bc@freeuk.com> writes:
    On 16/09/2026 12:47, David Brown wrote:
    On 16/09/2026 12:21, bart wrote:

    The recent example of those SDL3 headers is a good one. Even without >>>>> needing to change the C language, or have super-fast compilers for it, >>>>> those headers are grossly inefficient.

    So what?

    I did the timings there.˙ The savings achievable from "instant" headers >>>> would be tiny fractions of a second.

    I don't really trust your figures. I've today done a mock-up of a
    streamlined header for SDL3.

    In this form it is a file of just over 6K lines (probably there's stuff
    that doesn't need to be there, but it will suffice for this test).

    So here are my figures for a single 'hello-world' test for SDL3:

    sdl.h newsdl.h (normal vs compact)
    gcc 0.88 seconds 0.34 seconds

    That seems to be "tiny fractions of a second" to me. Pointless
    optimization for no appreciable return, almost in the noise.


    This is for *one* C source file that contains little more than that
    header. Typically there are multiple source files containing code of
    their own that need compiling, and which might need there own header.

    This is spending the best part of a second compiling 1300 function >signatures; this is 1980s machine speed.

    Sure. Pull the other one. Early 80's compilers were often
    limited by the speed of the input file (e.g. 300 lines-per-minute
    compile speeds with a 300CPM card reader).


    You seem to be involved in developing new, higher performance
    processors, and yet you're happy to all see all that power wasted
    because people who write these bloated messes of code are so fucking lazy.

    Actually none of that power is wasted, because 99.999% of the available processor cycles are running compiled application code, not compiling code.

    Compiling code is in the noise when considering modern workloads
    on PCs or servers.

    --- 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 16 20:21:19 2026
    On 16/09/2026 19:34, Scott Lurndal wrote:
    bart <bc@freeuk.com> writes:
    On 16/09/2026 18:33, Scott Lurndal wrote:
    bart <bc@freeuk.com> writes:
    On 16/09/2026 12:47, David Brown wrote:
    On 16/09/2026 12:21, bart wrote:

    The recent example of those SDL3 headers is a good one. Even without >>>>>> needing to change the C language, or have super-fast compilers for it, >>>>>> those headers are grossly inefficient.

    So what?

    I did the timings there.˙ The savings achievable from "instant" headers >>>>> would be tiny fractions of a second.

    I don't really trust your figures. I've today done a mock-up of a
    streamlined header for SDL3.

    In this form it is a file of just over 6K lines (probably there's stuff >>>> that doesn't need to be there, but it will suffice for this test).

    So here are my figures for a single 'hello-world' test for SDL3:

    sdl.h newsdl.h (normal vs compact)
    gcc 0.88 seconds 0.34 seconds

    That seems to be "tiny fractions of a second" to me. Pointless
    optimization for no appreciable return, almost in the noise.


    This is for *one* C source file that contains little more than that
    header. Typically there are multiple source files containing code of
    their own that need compiling, and which might need there own header.

    This is spending the best part of a second compiling 1300 function
    signatures; this is 1980s machine speed.

    Sure. Pull the other one. Early 80's compilers were often
    limited by the speed of the input file (e.g. 300 lines-per-minute
    compile speeds with a 300CPM card reader).

    I think it's you who's having a laugh. I said 1980s not 70s or 60s.

    In the 80s my own compilers probably managed some thousands of lines per seconds, running on microprocessors. They also all had at least floppy
    disk, and often hard drives.


    You seem to be involved in developing new, higher performance
    processors, and yet you're happy to all see all that power wasted
    because people who write these bloated messes of code are so fucking lazy.

    Actually none of that power is wasted, because 99.999% of the available processor cycles are running compiled application code, not compiling code.

    Compiling code is in the noise when considering modern workloads
    on PCs or servers.

    I'm sorry but it sounds very much like you don't have a clue.

    Just because your own builds take 10 minutes/elapsed and 75 minutes/cpu
    or whatever it was, you consider a 10-second build to be 'noise'?

    That's just your bad luck (if it is luck; more likely you're not curious enough to find the reason).

    In ten seconds I expect 30-50MB of compiled binary even on my slow machine.

    If it's taking that long to do very little, then there is something wrong.



    --- 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 16 20:30:28 2026
    On 16/09/2026 19:13, bart wrote:
    On 16/09/2026 16:58, Waldek Hebisch wrote:

    In any case, my stats show that 400K lines are still part of normal processing, while 150K lines are skipped due to false conditional blocks.

    Then I went back to one definition. This was fine, so the guards work.
    In that case, what the hell is it spending 400000 lines processing?!

    Some more investigation is needed via special tracking info added to my compiler. I will update this later.

    The problem was block- and line-comments. Their line-count was added to
    the total for normal tokenising and not that for skipping over false
    blocks, since both share the same comment routines.

    And there are a lot of comments, including quite a few outside the
    guards. I think 380K lines of comments are processed in all, including repeated passes through skipped blocks.

    Anyway the guards work, although it may still be interesting to try your (WH's) suggestion to recognise a primary header guard and abort the file immediately.



    --- 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 16 21:16:38 2026
    On 16/09/2026 20:30, bart wrote:
    On 16/09/2026 19:13, bart wrote:
    On 16/09/2026 16:58, Waldek Hebisch wrote:

    In any case, my stats show that 400K lines are still part of normal
    processing, while 150K lines are skipped due to false conditional blocks.

    Then I went back to one definition. This was fine, so the guards work.
    In that case, what the hell is it spending 400000 lines processing?!

    Some more investigation is needed via special tracking info added to
    my compiler. I will update this later.

    The problem was block- and line-comments. Their line-count was added to
    the total for normal tokenising and not that for skipping over false
    blocks, since both share the same comment routines.

    And there are a lot of comments, including quite a few outside the
    guards. I think 380K lines of comments are processed in all, including repeated passes through skipped blocks.

    Anyway the guards work, although it may still be interesting to try your (WH's) suggestion to recognise a primary header guard and abort the file immediately.


    I did try this via a bodge. It worked enough to eliminate most of the
    skipped comments. But it only made it (my C compiler) perhaps 20% faster
    at processing the full SDL3 headers.

    But skipping had already been tested to be not far off TCC, and so was
    comment scanning after some tweaks.

    Using the compact header, made it 4 times as fast.
    Conclusion: nothing really. C builds /could/ be made significantly
    faster when using large libraries across lots of modules, without
    needing to use workarounds, makefiles etc.

    But not one person had anything positive to say about it, and two have
    been hostile. A nice attitude.

    Anyway it was an interesting exercise for me, but if I use such a
    library for real, it will be via the generated bindings in my language.
    And the compiler for that has no such problems.

    The overheads of processing 4K declarations literally is some
    single-figure milliseconds per build.


    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From bart@3:633/10 to All on Thu Sep 17 00:36:54 2026
    On 16/09/2026 16:53, David Brown wrote:
    On 16/09/2026 16:20, bart wrote:

    Another advantage is that the header is a single file that is easy to
    use, copy, bundle etc. You don't need - I options.

    My test file contained a single line :

    ˙˙˙˙#include <SDL2/SDL.h>

    and compiled with

    ˙˙˙˙gcc -c test.c

    There are no -I options.

    Where is your SDL2 folder located relative to the current directory?

    Was there some installation process that put the headers in a place
    where gcc will look for it without being told? Does it involve using 'pkg-config'?

    Mine is in the current directory (that is, ./SDL3 is a folder that
    contains the headers). gcc doesn't work without '-I.' on either OS:

    c:\sdl>wsl
    root@DESKTOP-11:/mnt/c/sdl# cat s.c
    #include <SDL3/SDL.h>

    root@DESKTOP-11:/mnt/c/sdl# gcc -c s.c
    s.c:1:10: fatal error: SDL3/SDL.h: No such file or directory
    1 | #include <SDL3/SDL.h>
    | ^~~~~~~~~~~~
    compilation terminated.

    c:\sdl>gcc -c s.c
    s.c:1:10: fatal error: SDL3/SDL.h: No such file or directory
    1 | #include <SDL3/SDL.h>
    | ^~~~~~~~~~~~
    compilation terminated.



    Single header files are not particularly exciting for a library like
    this.

    Why not? stb_image works fine as a single header for example (which also contains the implementation). There are even sites that list
    single-header libraries.

    It is convenient for a user to have a library presented as just one
    file. The binary SDL3.DLL is one file; what possible advantage is there,
    to the user, for SDL.h to be anything other than a single self-contained
    file too?

    There is also the question of transparency: if there are two files (.dll
    and .h) I can see easily if they are present or not, rather than be a sprawling mess buried somewhere in your file system.



    --- 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 16 16:59:19 2026
    bart <bc@freeuk.com> writes:
    On 16/09/2026 16:53, David Brown wrote:
    On 16/09/2026 16:20, bart wrote:
    Another advantage is that the header is a single file that is easy
    to use, copy, bundle etc. You don't need - I options.
    My test file contained a single line :
    ˙˙˙˙#include <SDL2/SDL.h>
    and compiled with
    ˙˙˙˙gcc -c test.c
    There are no -I options.

    Where is your SDL2 folder located relative to the current directory?

    On my system (Ubuntu 24.04), it's "/usr/include/SDL2". David's
    system is probably similar.

    Was there some installation process that put the headers in a place
    where gcc will look for it without being told? Does it involve using 'pkg-config'?

    Yes, installing the Ubuntu package "libsdl2-dev" created and
    populated the /usr/include/SDL2 directory, among other things.
    That's a typical approach for Unix-like systems.

    pkg-config does know about sdl2, but "#include <SDL2/SDL.h>" appears
    to work without invoking pkg-config. There may be more to it than
    that, but I don't use SDL so I haven't looked into it.

    I have no idea how you'd set it up on Windows, but ...

    Mine is in the current directory (that is, ./SDL3 is a folder that
    contains the headers). gcc doesn't work without '-I.' on either OS:

    Did you set that up manually? If you had two projects that use SDL,
    would you have to create "./SDL3" folders in both of them?

    [...]

    --
    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 bart@3:633/10 to All on Thu Sep 17 01:49:43 2026
    On 17/09/2026 00:59, Keith Thompson wrote:
    bart <bc@freeuk.com> writes:
    On 16/09/2026 16:53, David Brown wrote:
    On 16/09/2026 16:20, bart wrote:
    Another advantage is that the header is a single file that is easy
    to use, copy, bundle etc. You don't need - I options.
    My test file contained a single line :
    ˙˙˙˙#include <SDL2/SDL.h>
    and compiled with
    ˙˙˙˙gcc -c test.c
    There are no -I options.

    Where is your SDL2 folder located relative to the current directory?

    On my system (Ubuntu 24.04), it's "/usr/include/SDL2". David's
    system is probably similar.

    Was there some installation process that put the headers in a place
    where gcc will look for it without being told? Does it involve using
    'pkg-config'?

    Yes, installing the Ubuntu package "libsdl2-dev" created and
    populated the /usr/include/SDL2 directory, among other things.
    That's a typical approach for Unix-like systems.

    pkg-config does know about sdl2, but "#include <SDL2/SDL.h>" appears
    to work without invoking pkg-config. There may be more to it than
    that, but I don't use SDL so I haven't looked into it.

    I have no idea how you'd set it up on Windows, but ...

    And I've no idea where gcc would look for its headers, other than where
    it keeps its system headers, or how to set it up to look permanently in certain places.


    Mine is in the current directory (that is, ./SDL3 is a folder that
    contains the headers). gcc doesn't work without '-I.' on either OS:

    Did you set that up manually? If you had two projects that use SDL,
    would you have to create "./SDL3" folders in both of them?
    For this test I wanted the simplest possible set up. If using it for
    real then I'd have to choose a centralised place to them, and impart
    that info to the compiler.

    This is where a single compact header can make things very easy:

    c:\demo>dir
    16/09/2026 13:57 304,760 newsdl.h
    02/09/2026 17:24 5,380,925 SDL3.dll
    08/09/2026 19:25 2,196 test.c

    test.c is my app; SDL3.dll is the library; and newsdl.h is the compacted interface. I could add one more file (bcc.exe) and I would have
    everything needed to write some SDL programs.

    I could copy them to a memory stick for example, whereas a gcc
    installation is big and messy.

    This is it in action:

    c:\demo>bcc test sdl3.dll
    Compiling test.c to test.exe

    c:\demo>gcc test.c sdl3.dll -o text

    c:\demo>tcc test.c sdl3.dll


    --- 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 16 19:43:15 2026
    bart <bc@freeuk.com> writes:
    On 17/09/2026 00:59, Keith Thompson wrote:
    bart <bc@freeuk.com> writes:
    On 16/09/2026 16:53, David Brown wrote:
    On 16/09/2026 16:20, bart wrote:
    Another advantage is that the header is a single file that is easy
    to use, copy, bundle etc. You don't need - I options.
    My test file contained a single line :
    ˙˙˙˙#include <SDL2/SDL.h>
    and compiled with
    ˙˙˙˙gcc -c test.c
    There are no -I options.

    Where is your SDL2 folder located relative to the current directory?
    On my system (Ubuntu 24.04), it's "/usr/include/SDL2". David's
    system is probably similar.

    Was there some installation process that put the headers in a place
    where gcc will look for it without being told? Does it involve using
    'pkg-config'?

    Yes, installing the Ubuntu package "libsdl2-dev" created and
    populated the /usr/include/SDL2 directory, among other things.
    That's a typical approach for Unix-like systems.
    pkg-config does know about sdl2, but "#include <SDL2/SDL.h>" appears
    to work without invoking pkg-config. There may be more to it than
    that, but I don't use SDL so I haven't looked into it.
    I have no idea how you'd set it up on Windows, but ...

    And I've no idea where gcc would look for its headers, other than
    where it keeps its system headers, or how to set it up to look
    permanently in certain places.

    I acknowledge that you don't know. I'm not going to assume that you
    want to know. If you do, I suggest asking elsewhere, since it's a
    question about gcc on Windows, not about the C language.

    As you know, gcc was originally designed to work on Unix-like systems.
    Windows support is an afterthought.

    Mine is in the current directory (that is, ./SDL3 is a folder that
    contains the headers). gcc doesn't work without '-I.' on either OS:

    Did you set that up manually? If you had two projects that use SDL,
    would you have to create "./SDL3" folders in both of them?

    For this test I wanted the simplest possible set up. If using it for
    real then I'd have to choose a centralised place to them, and impart
    that info to the compiler.

    Fair enough.

    This is where a single compact header can make things very easy:
    [snip]

    In my experience installing and using software, having a single
    compact header doesn't make a lot of difference. I follow the
    usual conventions for the OS or library I'm using. Typically a
    man page will tell me what #include directive(s) I need. I often
    don't know or care whether the header includes other headers. YMMV.

    [...]

    --
    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 Thu Sep 17 02:56:23 2026
    bart <bc@freeuk.com> wrote:
    On 16/09/2026 20:30, bart wrote:
    On 16/09/2026 19:13, bart wrote:
    On 16/09/2026 16:58, Waldek Hebisch wrote:

    In any case, my stats show that 400K lines are still part of normal
    processing, while 150K lines are skipped due to false conditional blocks. >>>
    Then I went back to one definition. This was fine, so the guards work.
    In that case, what the hell is it spending 400000 lines processing?!

    Some more investigation is needed via special tracking info added to
    my compiler. I will update this later.

    The problem was block- and line-comments. Their line-count was added to
    the total for normal tokenising and not that for skipping over false
    blocks, since both share the same comment routines.

    And there are a lot of comments, including quite a few outside the
    guards. I think 380K lines of comments are processed in all, including
    repeated passes through skipped blocks.

    Anyway the guards work, although it may still be interesting to try your
    (WH's) suggestion to recognise a primary header guard and abort the file
    immediately.


    I did try this via a bodge. It worked enough to eliminate most of the skipped comments. But it only made it (my C compiler) perhaps 20% faster
    at processing the full SDL3 headers.

    But skipping had already been tested to be not far off TCC, and so was comment scanning after some tweaks.

    There is still question were the time goes? You say that skipping
    is fast. But after you skip comments and false branches of conditionals
    you should have essentially the same thing as your compact header.
    So, where is the problem? In evaluating conditions? In opening
    files?

    Using the compact header, made it 4 times as fast.
    Conclusion: nothing really. C builds /could/ be made significantly
    faster when using large libraries across lots of modules, without
    needing to use workarounds, makefiles etc.

    But not one person had anything positive to say about it, and two have
    been hostile. A nice attitude.

    All other things being equal faster is better. But there is long
    way before such speedup is common. It seems that I have an SDL2
    sources on my computer so I did a little experiment. Trying

    cpp -E -dD SDL.h

    I get 63491 lines. '-dD' instructs 'cpp' to preserve '#define' lines,
    so I think that the result is usable as a replacement header.
    The result contains 14733 empty lines, and 2512 lines specifying
    line numbers (both are needed to present original line numbers in
    compiler messages). Removing both of the above still leaves
    46246 lines. There is 5715 lines begining with 'extern',
    3912 lines begining with '__attribute__', 3498 '#define' lines,
    463 lines begining with 'typedef', 44 lines begining with 'struct'.

    I see enum declaration, struct declarations seem to be rather
    large, each '__attribute__' line seem to be part of declaration
    of inline function.

    So, there is way more stuff than the 4000 lines that you report.
    Clearly processing them takes more time than in the case that
    you report. And presumably without all those inline functions
    (probably 20000 lines) resulting code will be slower.

    There are few hundred '#undef' lines, they are probably junk,
    but most of 46246 lines above seem to be doing useful work.
    And actually, the 14733 empty lines and 2512 lines specifying
    line numbers improve compiler diagnostics, so are useful too.

    BTW, on my machine 'gcc -O2 -c tsdl.c' where 'tsdl.c' contains
    single '#include "SDL.h" takes 0.173s. Doing the same with
    'tsdl2.c' where 'tsdl2.c' is result of 'cpp -E -dD SDL.h'
    takes 0.133s. The 'cpp' command takes about '0.032s'. So,
    it seems that 'gcc' can skip lines at reasonable speed and
    that most of the time goes into processing of declarations.

    Dividing number of lines it seems that on my machine gcc is
    able to process about 340000 declaration lines per second.
    If your count of 0.5M lines applies to sources that I have,
    then the 'cpp' time would indicate that it can skip lines
    at effective speed of about 15M lines per second. Of course,
    since gcc/cpp implements include guards most of that is
    skipped by skipping whole files (which you may consider
    cheating), but looking at effect gcc speed of skipping lines
    seem to be impressive even using your criteria.

    --
    Waldek Hebisch

    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From tTh@3:633/10 to All on Thu Sep 17 09:24:13 2026
    On 9/17/26 02:49, bart wrote:

    And I've no idea where gcc would look for its headers, other than where
    it keeps its system headers, or how to set it up to look permanently in certain places.

    You just have to read the fscking manual.

    https://gcc.gnu.org/onlinedocs/gcc/Environment-Variables.html

    But as everyone knows, learning new things isn't
    part of your philosophy...

    --
    ** **
    * tTh des Bourtoulots *
    * http://maison.tth.netlib.re/ *
    ** **

    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From bart@3:633/10 to All on Thu Sep 17 11:29:27 2026
    On 17/09/2026 08:24, tTh wrote:
    On 9/17/26 02:49, bart wrote:

    And I've no idea where gcc would look for its headers, other than
    where it keeps its system headers, or how to set it up to look
    permanently in certain places.

    ˙˙ You just have to read the fscking manual.

    https://gcc.gnu.org/onlinedocs/gcc/Environment-Variables.html

    Nobody uses environment variables any more. In any case, none of those
    listed are set. So I still don't know how gcc even manages to find its
    own system headers. But I don't care.

    gcc on Windows is poor at this anyway: if I have two gcc versions
    installed, then they clash, and gcc.exe doesn't appear to use paths
    relative to itself to find its dependent binaries.

    ˙˙ But as everyone knows, learning new things isn't
    ˙˙ part of your philosophy...

    I don't care about individual compilers, especially gcc which is a PITA
    in working differently from other C compilers, apart from those which slavishly copy all it behaviours. Examples:

    Compile prog.c to prog.exe:
    Produces:

    bcc prog prog.exe
    tcc prog.c prog.exe

    gcc proc.c a.exe
    gcc prog.c -o prog prog.exe

    Compile prog.c to prog.dll:

    bcc -dll prog prog.dll
    tcc -shared prog.c prog.dll

    gcc -shared proc.c a.exe
    gcc -shared prog.c -o prog prog.exe
    gcc -shared prog.c -o prog.dll prog.dll

    Here it takes 3 goes with gcc to do the right thing! It doesn't help
    that it doesn't tell you what file it just wrote.

    Oh, I should use '--verbose'? That produces the pile of crap shown
    below, which is so helpful! This is bcc in action::

    c:\c>bcc -dll prog
    Compiling prog.c to prog.dll

    As a driver program gcc is a POS. Look above at how far to the right
    that output column is in order to accommodate all its options!

    Oh, I should put such options into a file? OK, let's try that; here
    'input' contains:

    .\prog.c

    However, it doesn't work:

    c:\c>gcc @input
    cc1.exe: fatal error: .prog.c: No such file or directory
    compilation terminated.

    Apparently it doesn't like that '\', although it is a valid Windows path separator. I have to write '.\\prog.c' instead. Yet both bcc and tcc are
    fine with it.

    One more thing on that error message: it shows 'cc1.exe' which I don't
    see on my console. Apparently, gcc displays that in light grey, which is
    the same colour as my background! But for the actual error messages, it
    sets the background to black - AND IT DOESN'T RESTORE THE COLOURS
    AFTERWARDS.

    Bastard. (TBF, Clang is worse: all the errors are shown as light grey,
    so I can't see them at all!)

    Any more bizarre quirks? Probably loads, and probably because that's how
    gcc or its predecessor worked on Unix in 1871 and it was impossible to
    ever change it.

    So you can keep your stinkin' compiler.


    -------------------------------------------------------
    Using built-in specs.
    COLLECT_GCC=gcc COLLECT_LTO_WRAPPER=C:/tdm/bin/../libexec/gcc/x86_64-w64-mingw32/14.2.0/lto-wrapper.exe
    OFFLOAD_TARGET_NAMES=nvptx-none
    Target: x86_64-w64-mingw32
    Configured with: ../configure --prefix=/R/winlibs_staging_msvcrt64/inst_gcc-14.2.0/share/gcc --build=x86_64-w64-mingw32 --host=x86_64-w64-mingw32 --enable-offload-targets=nvptx-none --with-pkgversion='MinGW-W64 x86_64-msvcrt-posix-seh, built by Brecht Sanders, r3'
    --with-tune=generic --enable-checking=release --enable-threads=posix --disable-sjlj-exceptions --disable-libunwind-exceptions --disable-serial-configure --disable-bootstrap --enable-host-shared --enable-plugin --disable-default-ssp --disable-rpath --disable-libstdcxx-debug --disable-version-specific-runtime-libs --disable-symvers --enable-languages=c,c++,fortran,lto,objc,obj-c++ --disable-gold --disable-nls --disable-stage1-checking --disable-win32-registry --disable-multilib --enable-ld
    --enable-libquadmath --enable-libada --enable-libssp --enable-libstdcxx --enable-lto --enable-fully-dynamic-string --enable-libgomp
    --enable-graphite --enable-mingw-wildcard --enable-libstdcxx-time --enable-libstdcxx-pch
    --with-mpc=/c/Prog/winlibs_staging_msvcrt/custombuilt64 --with-mpfr=/c/Prog/winlibs_staging_msvcrt/custombuilt64 --with-gmp=/c/Prog/winlibs_staging_msvcrt/custombuilt64 --with-isl=/c/Prog/winlibs_staging_msvcrt/custombuilt64 --disable-libstdcxx-backtrace --enable-install-libiberty
    --enable-__cxa_atexit --without-included-gettext
    --with-diagnostics-color=auto --enable-clocale=generic --with-libiconv --with-system-zlib --with-build-sysroot=/R/winlibs_staging_msvcrt64/gcc-14.2.0/build_mingw/mingw-w64
    CFLAGS='-I/c/Prog/winlibs_staging_msvcrt/custombuilt64/include/libdl-win32
    -march=nocona -msahf -mtune=generic -O2 -Wno-error=format' CXXFLAGS='-Wno-int-conversion -march=nocona -msahf -mtune=generic -O2' LDFLAGS='-pthread -Wl,--no-insert-timestamp -Wl,--dynamicbase -Wl,--high-entropy-va -Wl,--nxcompat -Wl,--tsaware' LD=/c/Prog/winlibs_staging_msvcrt/custombuilt64/share/binutils/bin/ld.exe Thread model: posix
    Supported LTO compression algorithms: zlib zstd
    gcc version 14.2.0 (MinGW-W64 x86_64-msvcrt-posix-seh, built by Brecht Sanders, r3)
    COLLECT_GCC_OPTIONS='-shared' '-v' '-mtune=generic' '-march=x86-64'
    '-dumpdir' 'a-'
    C:/tdm/bin/../libexec/gcc/x86_64-w64-mingw32/14.2.0/cc1.exe -quiet -v -iprefix C:/tdm/bin/../lib/gcc/x86_64-w64-mingw32/14.2.0/ -D_REENTRANT
    prog.c -quiet -dumpdir a- -dumpbase prog.c -dumpbase-ext .c
    -mtune=generic -march=x86-64 -version -o C:\Users\44775\AppData\Local\Temp\ccpHFYOB.s
    GNU C17 (MinGW-W64 x86_64-msvcrt-posix-seh, built by Brecht Sanders, r3) version 14.2.0 (x86_64-w64-mingw32)
    compiled by GNU C version 14.2.0, GMP version 6.3.0, MPFR version 4.2.1, MPC version 1.3.1, isl version isl-0.27-GMP

    GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072 ignoring duplicate directory "C:/tdm/lib/gcc/../../lib/gcc/x86_64-w64-mingw32/14.2.0/include"
    ignoring nonexistent directory "R:/winlibs_staging_msvcrt64/inst_gcc-14.2.0/share/gcc/include"
    ignoring nonexistent directory "/R/winlibs_staging_msvcrt64/inst_gcc-14.2.0/share/gcc/include"
    ignoring duplicate directory "C:/tdm/lib/gcc/../../lib/gcc/x86_64-w64-mingw32/14.2.0/include-fixed"
    ignoring duplicate directory "C:/tdm/lib/gcc/../../lib/gcc/x86_64-w64-mingw32/14.2.0/../../../../x86_64-w64-mingw32/include"
    ignoring nonexistent directory "/mingw/include"
    #include "..." search starts here:
    #include <...> search starts here:
    C:/tdm/bin/../lib/gcc/x86_64-w64-mingw32/14.2.0/include
    C:/tdm/bin/../lib/gcc/x86_64-w64-mingw32/14.2.0/../../../../include
    C:/tdm/bin/../lib/gcc/x86_64-w64-mingw32/14.2.0/include-fixed
    C:/tdm/bin/../lib/gcc/x86_64-w64-mingw32/14.2.0/../../../../x86_64-w64-mingw32/include
    End of search list.
    Compiler executable checksum: 63b0164ba34d2bddc0314ced79a81f9e COLLECT_GCC_OPTIONS='-shared' '-v' '-mtune=generic' '-march=x86-64'
    '-dumpdir' 'a-'
    C:/tdm/bin/../lib/gcc/x86_64-w64-mingw32/14.2.0/../../../../x86_64-w64-mingw32/bin/as.exe -v -o C:\Users\44775\AppData\Local\Temp\ccMkclh8.o C:\Users\44775\AppData\Local\Temp\ccpHFYOB.s
    GNU assembler version 2.44 (x86_64-w64-mingw32) using BFD version
    (Binutils for MinGW-W64 x86_64, built by Brecht Sanders, r3) 2.44 COMPILER_PATH=C:/tdm/bin/../libexec/gcc/x86_64-w64-mingw32/14.2.0/;C:/tdm/bin/../libexec/gcc/;C:/tdm/bin/../lib/gcc/x86_64-w64-mingw32/14.2.0/../../../../x86_64-w64-mingw32/bin/
    LIBRARY_PATH=C:/tdm/bin/../lib/gcc/x86_64-w64-mingw32/14.2.0/;C:/tdm/bin/../lib/gcc/;C:/tdm/bin/../lib/gcc/x86_64-w64-mingw32/14.2.0/../../../../x86_64-w64-mingw32/lib/../lib/;C:/tdm/bin/../lib/gcc/x86_64-w64-mingw32/14.2.0/../../../../lib/;C:/tdm/bin/../lib/gcc/x86_64-w64-mingw32/14.2.0/../../../../x86_64-w64-mingw32/lib/;C:/tdm/bin/../lib/gcc/x86_64-w64-mingw32/14.2.0/../../../
    COLLECT_GCC_OPTIONS='-shared' '-v' '-mtune=generic' '-march=x86-64'
    '-dumpdir' 'a.'
    C:/tdm/bin/../libexec/gcc/x86_64-w64-mingw32/14.2.0/collect2.exe
    -plugin
    C:/tdm/bin/../libexec/gcc/x86_64-w64-mingw32/14.2.0/liblto_plugin.dll -plugin-opt=C:/tdm/bin/../libexec/gcc/x86_64-w64-mingw32/14.2.0/lto-wrapper.exe
    -plugin-opt=-fresolution=C:\Users\44775\AppData\Local\Temp\cctuIjoG.res -plugin-opt=-pass-through=-lmingw32 -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lmingwex -plugin-opt=-pass-through=-lmsvcrt -plugin-opt=-pass-through=-lkernel32 -plugin-opt=-pass-through=-lpthread -plugin-opt=-pass-through=-ladvapi32 -plugin-opt=-pass-through=-lshell32 -plugin-opt=-pass-through=-luser32 -plugin-opt=-pass-through=-lkernel32 -plugin-opt=-pass-through=-lmingw32 -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lmingwex -plugin-opt=-pass-through=-lmsvcrt -plugin-opt=-pass-through=-lkernel32 -m i386pep --shared -Bdynamic -e DllMainCRTStartup --enable-auto-image-base C:/tdm/bin/../lib/gcc/x86_64-w64-mingw32/14.2.0/../../../../x86_64-w64-mingw32/lib/../lib/dllcrt2.o
    C:/tdm/bin/../lib/gcc/x86_64-w64-mingw32/14.2.0/crtbegin.o -LC:/tdm/bin/../lib/gcc/x86_64-w64-mingw32/14.2.0
    -LC:/tdm/bin/../lib/gcc -LC:/tdm/bin/../lib/gcc/x86_64-w64-mingw32/14.2.0/../../../../x86_64-w64-mingw32/lib/../lib
    -LC:/tdm/bin/../lib/gcc/x86_64-w64-mingw32/14.2.0/../../../../lib -LC:/tdm/bin/../lib/gcc/x86_64-w64-mingw32/14.2.0/../../../../x86_64-w64-mingw32/lib
    -LC:/tdm/bin/../lib/gcc/x86_64-w64-mingw32/14.2.0/../../.. C:\Users\44775\AppData\Local\Temp\ccMkclh8.o -lmingw32 -lgcc_s -lgcc
    -lmingwex -lmsvcrt -lkernel32 -lpthread -ladvapi32 -lshell32 -luser32 -lkernel32 -lmingw32 -lgcc_s -lgcc -lmingwex -lmsvcrt -lkernel32 C:/tdm/bin/../lib/gcc/x86_64-w64-mingw32/14.2.0/crtend.o COLLECT_GCC_OPTIONS='-shared' '-v' '-mtune=generic' '-march=x86-64'
    '-dumpdir' 'a.'

    --- 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 Thu Sep 17 12:36:42 2026
    On 17/09/2026 01:36, bart wrote:
    On 16/09/2026 16:53, David Brown wrote:
    On 16/09/2026 16:20, bart wrote:

    Another advantage is that the header is a single file that is easy to
    use, copy, bundle etc. You don't need - I options.

    My test file contained a single line :

    ˙˙˙˙˙#include <SDL2/SDL.h>

    and compiled with

    ˙˙˙˙˙gcc -c test.c

    There are no -I options.

    Where is your SDL2 folder located relative to the current directory?

    /usr/include/SDL2


    Was there some installation process that put the headers in a place
    where gcc will look for it without being told? Does it involve using 'pkg-config'?

    "apt install libsdl2-dev", as I said. Linux distributions with other
    package managers will have a very similar method.


    Mine is in the current directory (that is, ./SDL3 is a folder that
    contains the headers). gcc doesn't work without '-I.' on either OS:

    ˙ c:\sdl>wsl
    ˙ root@DESKTOP-11:/mnt/c/sdl# cat s.c
    ˙ #include <SDL3/SDL.h>

    Do you not understand the difference between using <> and "" in #include directives? Roughly speaking (details are implementation-specific),
    using "SDL3/SDL.h" searches first the local directory and relative
    paths, and then moves on to system / toolchain include directories if
    that fails - using <SDL3/SDL.h> goes straight to the system / toolchain directories.

    So if you have SDL headers installed as part of the system libraries,
    the <> form is appropriate - it also ensures that you are getting the
    system library versions and not accidentally getting a local file of the
    same name. If you have the headers in your local directory (or in both places, but want the local version), use the "" form.



    ˙ root@DESKTOP-11:/mnt/c/sdl# gcc -c s.c
    ˙ s.c:1:10: fatal error: SDL3/SDL.h: No such file or directory
    ˙˙˙˙˙ 1 | #include <SDL3/SDL.h>
    ˙˙˙˙˙˙˙ |˙˙˙˙˙˙˙˙˙ ^~~~~~~~~~~~
    ˙ compilation terminated.

    ˙ c:\sdl>gcc -c s.c
    ˙ s.c:1:10: fatal error: SDL3/SDL.h: No such file or directory
    ˙˙˙˙˙ 1 | #include <SDL3/SDL.h>
    ˙˙˙˙˙˙˙ |˙˙˙˙˙˙˙˙˙ ^~~~~~~~~~~~
    ˙ compilation terminated.



    Single header files are not particularly exciting for a library like
    this.

    Why not? stb_image works fine as a single header for example (which also contains the implementation). There are even sites that list single-
    header libraries.

    I told you why.



    --- 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 Thu Sep 17 12:52:23 2026
    On 17/09/2026 02:49, bart wrote:
    On 17/09/2026 00:59, Keith Thompson wrote:
    bart <bc@freeuk.com> writes:
    On 16/09/2026 16:53, David Brown wrote:
    On 16/09/2026 16:20, bart wrote:
    Another advantage is that the header is a single file that is easy
    to use, copy, bundle etc. You don't need - I options.
    My test file contained a single line :
    ˙ ˙˙˙˙#include <SDL2/SDL.h>
    and compiled with
    ˙ ˙˙˙˙gcc -c test.c
    There are no -I options.

    Where is your SDL2 folder located relative to the current directory?

    On my system (Ubuntu 24.04), it's "/usr/include/SDL2".˙ David's
    system is probably similar.

    Was there some installation process that put the headers in a place
    where gcc will look for it without being told? Does it involve using
    'pkg-config'?

    Yes, installing the Ubuntu package "libsdl2-dev" created and
    populated the /usr/include/SDL2 directory, among other things.
    That's a typical approach for Unix-like systems.

    pkg-config does know about sdl2, but "#include <SDL2/SDL.h>" appears
    to work without invoking pkg-config.˙ There may be more to it than
    that, but I don't use SDL so I haven't looked into it.

    I have no idea how you'd set it up on Windows, but ...

    And I've no idea where gcc would look for its headers, other than where
    it keeps its system headers, or how to set it up to look permanently in certain places.

    touch empty.c
    gcc -E -v empty.c

    That will show you, amongst other things, the default include paths. On
    my system, it shows :

    #include "..." search starts here:
    #include <...> search starts here:
    /usr/lib/gcc/x86_64-linux-gnu/13/include
    /usr/local/include
    /usr/include/x86_64-linux-gnu
    /usr/include
    End of search list.




    Mine is in the current directory (that is, ./SDL3 is a folder that
    contains the headers). gcc doesn't work without '-I.' on either OS:

    Did you set that up manually?˙ If you had two projects that use SDL,
    would you have to create "./SDL3" folders in both of them?
    For this test I wanted the simplest possible set up. If using it for
    real then I'd have to choose a centralised place to them, and impart
    that info to the compiler.

    This is where a single compact header can make things very easy:

    ˙ c:\demo>dir
    ˙ 16/09/2026˙ 13:57˙˙˙˙˙˙˙˙˙˙ 304,760 newsdl.h
    ˙ 02/09/2026˙ 17:24˙˙˙˙˙˙˙˙ 5,380,925 SDL3.dll
    ˙ 08/09/2026˙ 19:25˙˙˙˙˙˙˙˙˙˙˙˙ 2,196 test.c

    It is also where using a decent OS appropriate for the task is even easier.


    test.c is my app; SDL3.dll is the library; and newsdl.h is the compacted interface. I could add one more file (bcc.exe) and I would have
    everything needed to write some SDL programs.

    I could copy them to a memory stick for example, whereas a gcc
    installation is big and messy.


    I copy gcc setups between systems (albeit cross-compilation toolchains).
    It's easy with scp, sshfs, rsync, network shares, or a USB stick. The cheapest USB drives I can find from my usual IT supplier are 32 GB - the biggest toolchain I have is about 1.2 GB for everything. The same
    applies to Linux and Windows.

    Sure, the process would be faster if the toolchain directories were
    smaller, but I only need to do it once or twice a year for new versions.

    The only time things are difficult is when some idiot device
    manufacturer thinks their Windows version should use an installer
    program that screws with the registry, environment variables or system
    paths.


    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From bart@3:633/10 to All on Thu Sep 17 13:03:40 2026
    On 17/09/2026 11:36, David Brown wrote:
    On 17/09/2026 01:36, bart wrote:
    On 16/09/2026 16:53, David Brown wrote:
    On 16/09/2026 16:20, bart wrote:

    Another advantage is that the header is a single file that is easy
    to use, copy, bundle etc. You don't need - I options.

    My test file contained a single line :

    ˙˙˙˙˙#include <SDL2/SDL.h>

    and compiled with

    ˙˙˙˙˙gcc -c test.c

    There are no -I options.

    Where is your SDL2 folder located relative to the current directory?

    /usr/include/SDL2


    Was there some installation process that put the headers in a place
    where gcc will look for it without being told? Does it involve using
    'pkg-config'?

    "apt install libsdl2-dev", as I said.˙ Linux distributions with other package managers will have a very similar method.

    My gcc Windows installation (I went back to 14.2 as it includes clang), includes 3000 .h files. They can't all be for the standard library!

    And 1200 .a archive files. So the approach there seems to be bundle
    headers and binaries for every possible library. But apparently not big
    ones like SDL.

    So I guess, if I copied the SDL3 folder to the same location it keeps
    stdio.h, it would also work without "-I".

    But only for this compiler, and not ideal when multiple headers are not
    tidily contained within their own folder.


    Mine is in the current directory (that is, ./SDL3 is a folder that
    contains the headers). gcc doesn't work without '-I.' on either OS:

    ˙˙ c:\sdl>wsl
    ˙˙ root@DESKTOP-11:/mnt/c/sdl# cat s.c
    ˙˙ #include <SDL3/SDL.h>

    Do you not understand the difference between using <> and "" in #include directives?˙ Roughly speaking (details are implementation-specific),

    Exactly, they are implementation-specific. Which can mean subtle
    differences in locating a file when already deep inside a nested header.

    My compiler actually treats <> and "" the same. That would normally be troublesome as a rogue "stdio.h" in the current path would override the
    system header.

    But my compiler's system headers are embedded, and it will look there
    first for /any/ input files. So that doesn't come up, unless I override
    that.



    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From bart@3:633/10 to All on Thu Sep 17 13:15:01 2026
    On 17/09/2026 11:52, David Brown wrote:
    On 17/09/2026 02:49, bart wrote:
    Was there some installation process that put the headers in a place
    where gcc will look for it without being told? Does it involve using
    'pkg-config'?

    Yes, installing the Ubuntu package "libsdl2-dev" created and
    populated the /usr/include/SDL2 directory, among other things.
    That's a typical approach for Unix-like systems.

    pkg-config does know about sdl2, but "#include <SDL2/SDL.h>" appears
    to work without invoking pkg-config.˙ There may be more to it than
    that, but I don't use SDL so I haven't looked into it.

    I have no idea how you'd set it up on Windows, but ...

    And I've no idea where gcc would look for its headers, other than
    where it keeps its system headers, or how to set it up to look
    permanently in certain places.

    touch empty.c
    gcc -E -v empty.c

    That will show you, amongst other things, the default include paths.˙ On
    my system, it shows :

    #include "..." search starts here:
    #include <...> search starts here:
    ˙/usr/lib/gcc/x86_64-linux-gnu/13/include
    ˙/usr/local/include
    ˙/usr/include/x86_64-linux-gnu
    ˙/usr/include
    End of search list.

    I got a lot more output than that. Then I noticed you said 'amongst
    other things'. So -v does not produce less output than --verbose!

    On my C compiler I used to have an option -paths which listed all the
    include paths it would use.

    I'm surprised that gcc, amongst it 1000s of options, doesn't have a
    dedicated one for this.





    Mine is in the current directory (that is, ./SDL3 is a folder that
    contains the headers). gcc doesn't work without '-I.' on either OS:

    Did you set that up manually?˙ If you had two projects that use SDL,
    would you have to create "./SDL3" folders in both of them?
    For this test I wanted the simplest possible set up. If using it for
    real then I'd have to choose a centralised place to them, and impart
    that info to the compiler.

    This is where a single compact header can make things very easy:

    ˙˙ c:\demo>dir
    ˙˙ 16/09/2026˙ 13:57˙˙˙˙˙˙˙˙˙˙ 304,760 newsdl.h
    ˙˙ 02/09/2026˙ 17:24˙˙˙˙˙˙˙˙ 5,380,925 SDL3.dll
    ˙˙ 08/09/2026˙ 19:25˙˙˙˙˙˙˙˙˙˙˙˙ 2,196 test.c

    It is also where using a decent OS appropriate for the task is even easier.

    Seem my remark about managing complexity below.


    test.c is my app; SDL3.dll is the library; and newsdl.h is the
    compacted interface. I could add one more file (bcc.exe) and I would
    have everything needed to write some SDL programs.

    I could copy them to a memory stick for example, whereas a gcc
    installation is big and messy.


    I copy gcc setups between systems (albeit cross-compilation toolchains).
    ˙It's easy with scp, sshfs, rsync, network shares, or a USB stick.˙ The cheapest USB drives I can find from my usual IT supplier are 32 GB - the biggest toolchain I have is about 1.2 GB for everything.˙ The same
    applies to Linux and Windows.

    Amazingly, my own tools would still fit on one 1.44MB floppy - uncompressed.

    I think the approach you and others use now is to manage bloat and
    complexity, or somehow hide it away under additional layers, rather than
    do anything about it.

    And the approach to keep things moving is to add extra hardware. If that doesn't work then avoid recompiling anything if at all possible!

    Mine are to actually keep things simple, and to keep on top of raw speed.

    The problem with not doing anything about complexity is that probably no
    one knows how it all works. So when it goes wrong...

    --- 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 Thu Sep 17 14:51:20 2026
    On 17/09/2026 14:03, bart wrote:
    On 17/09/2026 11:36, David Brown wrote:
    On 17/09/2026 01:36, bart wrote:
    On 16/09/2026 16:53, David Brown wrote:
    On 16/09/2026 16:20, bart wrote:

    Another advantage is that the header is a single file that is easy
    to use, copy, bundle etc. You don't need - I options.

    My test file contained a single line :

    ˙˙˙˙˙#include <SDL2/SDL.h>

    and compiled with

    ˙˙˙˙˙gcc -c test.c

    There are no -I options.

    Where is your SDL2 folder located relative to the current directory?

    /usr/include/SDL2


    Was there some installation process that put the headers in a place
    where gcc will look for it without being told? Does it involve using
    'pkg-config'?

    "apt install libsdl2-dev", as I said.˙ Linux distributions with other
    package managers will have a very similar method.

    My gcc Windows installation (I went back to 14.2 as it includes clang), includes 3000 .h files. They can't all be for the standard library!


    As you well know, there is no such thing as a standard "gcc Windows" installation - there are multiple different packagings of gcc with
    different choices of libraries and other tools. I am not sure it is
    going to be very helpful if you say exactly which Windows gcc
    installation you have, but there can be huge variations between them.

    First off, you can expect that you have C++ support as well as C support
    - and C++ has far more standard headers than C. Many of these are named without ".h", but real-world C++ standard libraries implement them with countless ".h" files. Looking inside the directories for the standard
    ARM gcc cross-toolchain package for embedded devices, version 15.2, I
    see 1880 header files of which 1205 are in C++ specific directories.

    Then there are generally lots for extensions to the standard library -
    most C libraries have a fair bit more than the standard libraries.
    There are target-specific headers, processor-specific headers (for
    "intrinsic" functions), and often many headers that are included by
    several of the others to reduce duplication and maintenance. There will
    be lots of OS-specific or "system" headers (for Linux, Windows, whatever).

    And 1200 .a archive files. So the approach there seems to be bundle
    headers and binaries for every possible library. But apparently not big
    ones like SDL.


    Standard and additional libraries are often split into multiple parts. Traditionally, "libc.a" contains most functions, and "libm.a" contains
    the floating point libraries. But there can be more splits, and
    additional libraries for other parts - a toolchain installation often
    includes many other things than just the standards-defined library. And
    then for each set of static libraries, there can be a large number of
    builds optimised for different target variants, different choices of
    compiler flags (like optimisation, or debug support), and so on. My cross-compiler toolchain has 780 ".a" files, for variants of about a
    dozen different ARM cores, each with perhaps 4 choices of floating point hardware support.

    But a standard toolchain installation is not going to include SDL
    libraries and headers, unless it was for a platform that had that as a necessity. If SDL was considered worthy for inclusion by standard,
    there would be a thousand other "worthy" libraries to include too.

    So I guess, if I copied the SDL3 folder to the same location it keeps stdio.h, it would also work without "-I".


    I guess so. But I would not do that unless it was controlled by some
    kind of package manager - keeping everything consistent and avoiding
    conflicts can be quite an effort.

    You also don't need any "-I" flags if you used the more appropriate (for
    your setup) use of #include "SDL3/SDL.h" rather than the <> system
    include form.

    It is also normal to have a common place for include files, like
    /usr/include and /usr/local/include. There is no standard for this in Windows, but you might find at least that different versions of the same
    gcc Windows packages look in common directories.

    But only for this compiler, and not ideal when multiple headers are not tidily contained within their own folder.


    Fortunately most (IME) libraries that have multiple headers /do/ keep
    them tidily in their own folder.


    Mine is in the current directory (that is, ./SDL3 is a folder that
    contains the headers). gcc doesn't work without '-I.' on either OS:

    ˙˙ c:\sdl>wsl
    ˙˙ root@DESKTOP-11:/mnt/c/sdl# cat s.c
    ˙˙ #include <SDL3/SDL.h>

    Do you not understand the difference between using <> and "" in
    #include directives?˙ Roughly speaking (details are implementation-
    specific),

    Exactly, they are implementation-specific. Which can mean subtle
    differences in locating a file when already deep inside a nested header.


    It's not /that/ difficult - I explained it in a single sentence. And
    while it's "implementation-specific" according to the C standards, the
    same simple, basic system is used by virtually all C compilers, and
    virtually all C code. Use "" for application-specific headers, and <>
    for toolchain and system-installed headers.

    My compiler actually treats <> and "" the same. That would normally be troublesome as a rogue "stdio.h" in the current path would override the system header.


    Well, you can always complain to that compiler's development team, and
    ask them to follow the norms.

    But my compiler's system headers are embedded, and it will look there
    first for /any/ input files. So that doesn't come up, unless I override that.




    --- 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 Thu Sep 17 15:16:54 2026
    On 17/09/2026 14:15, bart wrote:
    On 17/09/2026 11:52, David Brown wrote:
    On 17/09/2026 02:49, bart wrote:
    Was there some installation process that put the headers in a place
    where gcc will look for it without being told? Does it involve using >>>>> 'pkg-config'?

    Yes, installing the Ubuntu package "libsdl2-dev" created and
    populated the /usr/include/SDL2 directory, among other things.
    That's a typical approach for Unix-like systems.

    pkg-config does know about sdl2, but "#include <SDL2/SDL.h>" appears
    to work without invoking pkg-config.˙ There may be more to it than
    that, but I don't use SDL so I haven't looked into it.

    I have no idea how you'd set it up on Windows, but ...

    And I've no idea where gcc would look for its headers, other than
    where it keeps its system headers, or how to set it up to look
    permanently in certain places.

    touch empty.c
    gcc -E -v empty.c

    That will show you, amongst other things, the default include paths.
    On my system, it shows :

    #include "..." search starts here:
    #include <...> search starts here:
    ˙˙/usr/lib/gcc/x86_64-linux-gnu/13/include
    ˙˙/usr/local/include
    ˙˙/usr/include/x86_64-linux-gnu
    ˙˙/usr/include
    End of search list.

    I got a lot more output than that. Then I noticed you said 'amongst
    other things'. So -v does not produce less output than --verbose!


    Yes. You might think it strange, but I only posted the relevant lines
    here. There were a total of 31 lines from that command - it was not
    difficult to spot the ones relevant to the include paths.

    On my C compiler I used to have an option -paths which listed all the include paths it would use.

    I'm surprised that gcc, amongst it 1000s of options, doesn't have a dedicated one for this.


    I've never needed to see the list of paths before - they are all
    entirely obvious and standard, and "just work". Why would a compiler
    need to add a specific option for something that is rarely required and
    where there is a simple and fairly obvious common option ("-v", or "--verbose") to get the information?


    I think the approach you and others use now is to manage bloat and complexity, or somehow hide it away under additional layers, rather than
    do anything about it.


    My approach is to care about things that are worth caring about, and not bother about things that are not worth bothering about.

    I need tools that do the job I need them to do.

    I don't need "as small as possible" - I need "small enough that their
    size is not an inconvenience". I don't need "as fast as possible" - I
    need "fast enough that their speed is not an inconvenience". Small
    enough is small enough. Fast enough is fast enough. After that,
    smaller or faster is irrelevant and not part of the consideration for
    picking a tool.

    On the other hand, slightly better code optimisation can mean longer
    battery life, smaller and cheaper hardware, or more functionality in my program. A bit more static error checking can mean bugs caught during development and building, rather than during testing or after
    deployment. Better standards conformance can mean more portable code
    and easier testing, support for newer standards and useful extensions
    means more expressive, re-usable or maintainable source code, better optimisation, and more static error checking.

    I do software development. I don't spend my days copying compilers to
    floppy disks or trying to run tools on systems from last century. I am
    not interested in how quickly a compiler can compile an almost-empty
    test file, 50 times sequentially. I don't care if "bcc test.c" runs
    faster than "gcc test.c" when "bcc test.c" is no more use to me than
    "cat test.c > /dev/null".

    By all means, play with your "benchmarks" if you enjoy doing so. But
    stop expecting anyone else to care.




    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From bart@3:633/10 to All on Thu Sep 17 14:32:37 2026
    On 17/09/2026 13:51, David Brown wrote:
    On 17/09/2026 14:03, bart wrote:

    My gcc Windows installation (I went back to 14.2 as it includes
    clang), includes 3000 .h files. They can't all be for the standard
    library!


    As you well know, there is no such thing as a standard "gcc Windows" installation - there are multiple different packagings of gcc with
    different choices of libraries and other tools.˙ I am not sure it is
    going to be very helpful if you say exactly which Windows gcc
    installation you have, but there can be huge variations between them.

    If interested it was from winlibs.com. (The site looks like something
    from the 1990s but it has versions up 16.2.0.)

    Do you not understand the difference between using <> and "" in
    #include directives?˙ Roughly speaking (details are implementation-
    specific),

    Exactly, they are implementation-specific. Which can mean subtle
    differences in locating a file when already deep inside a nested header.


    It's not /that/ difficult - I explained it in a single sentence.˙ And
    while it's "implementation-specific" according to the C standards, the
    same simple, basic system is used by virtually all C compilers, and virtually all C code.˙ Use "" for application-specific headers, and <>
    for toolchain and system-installed headers.

    It's a bit more elaborate than that. Here are the inputs the algorithm
    might work with when it tries to find a new header file:

    * Whether "" or <> is used

    * Whether the file-spec is absolute or relative

    * The ordered list of locations that it looks for system headers

    * The set of include paths given via -I or equivalent options (I
    assume these are ordered too)

    * The directory from where the compiler was invoked ('cwd')

    * The directory (and possibly other locations relative to that) where
    the compiler binary lives

    * The path of the main .c source file

    * The current stack of nested include file locations, including
    that of the current include file

    * (For mine at least) the set of embedded files within the compiler, and
    any further options that can alter the behaviour

    I'd like to know what you would consider difficult! (Apparently, nothing.)

    The algorithm has to decide how to use this information. However what is implied is that if it can't find the file in one location, it will try somewhere else, provided an absolute path was not used.

    I have problem with that: if header file is accidentally deleted or
    renamed, it might find a header with the same name elsewhere, but it
    will now be the wrong one, or the wrong version.

    (For this reason, the compiler for my language will only ever look in
    one place on disk for any file, even though the module scheme simplifies
    the process immensely.)


    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From bart@3:633/10 to All on Thu Sep 17 15:25:45 2026
    On 17/09/2026 14:16, David Brown wrote:
    On 17/09/2026 14:15, bart wrote:
    On 17/09/2026 11:52, David Brown wrote:
    On 17/09/2026 02:49, bart wrote:
    Was there some installation process that put the headers in a place >>>>>> where gcc will look for it without being told? Does it involve using >>>>>> 'pkg-config'?

    Yes, installing the Ubuntu package "libsdl2-dev" created and
    populated the /usr/include/SDL2 directory, among other things.
    That's a typical approach for Unix-like systems.

    pkg-config does know about sdl2, but "#include <SDL2/SDL.h>" appears >>>>> to work without invoking pkg-config.˙ There may be more to it than
    that, but I don't use SDL so I haven't looked into it.

    I have no idea how you'd set it up on Windows, but ...

    And I've no idea where gcc would look for its headers, other than
    where it keeps its system headers, or how to set it up to look
    permanently in certain places.

    touch empty.c
    gcc -E -v empty.c

    That will show you, amongst other things, the default include paths.
    On my system, it shows :

    #include "..." search starts here:
    #include <...> search starts here:
    ˙˙/usr/lib/gcc/x86_64-linux-gnu/13/include
    ˙˙/usr/local/include
    ˙˙/usr/include/x86_64-linux-gnu
    ˙˙/usr/include
    End of search list.

    I got a lot more output than that. Then I noticed you said 'amongst
    other things'. So -v does not produce less output than --verbose!


    Yes.˙ You might think it strange, but I only posted the relevant lines
    here.˙ There were a total of 31 lines from that command - it was not difficult to spot the ones relevant to the include paths.

    Always making excuses for gcc! I get 37 lines from it, but because many
    are long and wrap, my screen shows over 85 lines, with 25 of them
    scrolling off the top of the window. It looks a mess.

    On my C compiler I used to have an option -paths which listed all the
    include paths it would use.

    I'm surprised that gcc, amongst it 1000s of options, doesn't have a
    dedicated one for this.


    I've never needed to see the list of paths before - they are all
    entirely obvious and standard, and "just work".

    Yeah, everything 'just works' for you. But if ever it reports it can't
    find some header, you will want to know:

    (1) The list of locations that it will be looking

    (2) All the locations it's checked (this is not necessarily the
    same list; see my last post)


    ˙ Why would a compiler
    need to add a specific option for something that is rarely required and where there is a simple and fairly obvious common option ("-v", or "-- verbose") to get the information?

    That option is next to useless because it buries what you need in a
    mountain of junk.

    On the other hand, slightly better code optimisation can mean longer
    battery life, smaller and cheaper hardware, or more functionality in my program.

    Maybe you do get it after all. Using smaller, simpler, faster tools
    gives all those advantages too.

    It's a shame you don't see language tools in the same light as some of
    your applications.

    ˙ A bit more static error checking can mean bugs caught during
    development and building, rather than during testing or after
    deployment.

    A better language can also do that!

    ˙ Better standards conformance can mean more portable code
    and easier testing, support for newer standards and useful extensions
    means more expressive, re-usable or maintainable source code, better optimisation, and more static error checking.

    I do software development.

    So do I, but I develop experimental language tools. You want to get your applications (it will be more embedded systems stuff I expect) as small
    and efficient as possible.

    I do too.

    ˙ I don't spend my days copying compilers to
    floppy disks or trying to run tools on systems from last century.˙ I am
    not interested in how quickly a compiler can compile an almost-empty
    test file, 50 times sequentially.

    Come on, I sure you know what is involved in benchmarking. You often
    have to isolate some part if looking for a the bottleneck.

    But in this case the point of the test was to measure the impact of a
    large header used across a sizeable number of modules.

    This is the RAW impact. All that YOU can do, and are interested in, is
    in mitigating that (more cores, avoid recompiling etc).

    But I am interested in reducing that raw overhead.

    ˙ I don't care if "bcc test.c" runs
    faster than "gcc test.c" when "bcc test.c" is no more use to me than
    "cat test.c > /dev/null".

    This is the funny thing I've discovered when discussing compilers elsewhere:

    * When a compiler builds an app then the speed of that app is the most
    important thing in the world, no matter what the app is ...
    * ... unless the app is a compiler. Then its speed is the least
    important thing in the world!

    So, you care about your apps being fast; I care about /my/ apps being
    fast. Even for language tools, as they open up interesting new ways of
    working as well as being an interesting endeavour in itself.Now, it
    could be that there is some gross inefficiency in your tools that no one spotted, if everyone is as incurious and as tolerant as you.

    One way of telling is if there was an alternative product that does the
    same thing faster.

    Before you tell me that your prefered tool does that much more, remember
    the examples I gave of assemblers with a 10:1 disparity between fastest
    and slowest. There is no deep analysis or opimisation there. Some tools
    are just Slow.

    --- 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 Thu Sep 17 14:38:05 2026
    David Brown <david.brown@hesbynett.no> wrote:
    On 17/09/2026 14:15, bart wrote:

    I got a lot more output than that. Then I noticed you said 'amongst
    other things'. So -v does not produce less output than --verbose!


    Yes. You might think it strange, but I only posted the relevant lines
    here. There were a total of 31 lines from that command - it was not difficult to spot the ones relevant to the include paths.

    On my C compiler I used to have an option -paths which listed all the
    include paths it would use.

    I'm surprised that gcc, amongst it 1000s of options, doesn't have a
    dedicated one for this.


    I've never needed to see the list of paths before - they are all
    entirely obvious and standard, and "just work". Why would a compiler
    need to add a specific option for something that is rarely required and where there is a simple and fairly obvious common option ("-v", or "--verbose") to get the information?

    For the benefit of configure scripts? And for symmetry? I find
    options like:

    -print-search-dirs
    -print-multiarch
    ...
    -print-sysroot-headers-suffix

    but the last one apparently does not work in normal install (even
    for cross compilers), and the other seem to give no info about headers.

    --
    Waldek Hebisch

    --- 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 Thu Sep 17 17:05:41 2026
    On 17/09/2026 16:25, bart wrote:
    On 17/09/2026 14:16, David Brown wrote:
    On 17/09/2026 14:15, bart wrote:
    On 17/09/2026 11:52, David Brown wrote:
    On 17/09/2026 02:49, bart wrote:
    Was there some installation process that put the headers in a place >>>>>>> where gcc will look for it without being told? Does it involve using >>>>>>> 'pkg-config'?

    Yes, installing the Ubuntu package "libsdl2-dev" created and
    populated the /usr/include/SDL2 directory, among other things.
    That's a typical approach for Unix-like systems.

    pkg-config does know about sdl2, but "#include <SDL2/SDL.h>" appears >>>>>> to work without invoking pkg-config.˙ There may be more to it than >>>>>> that, but I don't use SDL so I haven't looked into it.

    I have no idea how you'd set it up on Windows, but ...

    And I've no idea where gcc would look for its headers, other than
    where it keeps its system headers, or how to set it up to look
    permanently in certain places.

    touch empty.c
    gcc -E -v empty.c

    That will show you, amongst other things, the default include paths.
    On my system, it shows :

    #include "..." search starts here:
    #include <...> search starts here:
    ˙˙/usr/lib/gcc/x86_64-linux-gnu/13/include
    ˙˙/usr/local/include
    ˙˙/usr/include/x86_64-linux-gnu
    ˙˙/usr/include
    End of search list.

    I got a lot more output than that. Then I noticed you said 'amongst
    other things'. So -v does not produce less output than --verbose!


    Yes.˙ You might think it strange, but I only posted the relevant lines
    here.˙ There were a total of 31 lines from that command - it was not
    difficult to spot the ones relevant to the include paths.

    Always making excuses for gcc! I get 37 lines from it, but because many
    are long and wrap, my screen shows over 85 lines, with 25 of them
    scrolling off the top of the window. It looks a mess.

    If gcc had a flag to show the include paths, and nothing but the include paths, you'd complain that you had to read through piles of
    documentation to find it. It does not seem to matter what inane,
    pointless task you and you alone think is vital, your life seems to
    revolve around saying that gcc is bad in every way. So what's next?
    gcc is a terrible tool because you find it harder to type "gcc" than "bcc" ?

    Sometimes you have sane points about weaknesses in C, or things that
    could be improved in gcc, clang, and other tools - or at least, they
    were sane points the first time you raised them rather than the
    hundredth time. But this moan is pathetic even by your standards.


    Oh, and does your fantastic OS not have scrollbars to see more lines of output? Are you stuck with terminal windows limited to 80 characters
    wide, just like we all used last century? Do you not know how to use
    the "less" command? (Oh, wait, "less" is only 42 years old - we could
    not expect Windows to have caught up with such basic tools in that time.
    But you can use "more".)


    On my C compiler I used to have an option -paths which listed all the
    include paths it would use.

    I'm surprised that gcc, amongst it 1000s of options, doesn't have a
    dedicated one for this.


    I've never needed to see the list of paths before - they are all
    entirely obvious and standard, and "just work".

    Yeah, everything 'just works' for you. But if ever it reports it can't
    find some header, you will want to know:

    (1) The list of locations that it will be looking

    (2) All the locations it's checked (this is not necessarily the
    ˙˙˙ same list; see my last post)


    Learn to use a computer for software development, and stop bleating when
    you actually have to lift a finger! Of course I have occasionally had a compile fail because my code references a missing header. When it
    happens I either find the header, or fix the typo in my code. We are
    not doing brain surgery here.

    If you can't program in C, and can't use normal C compilers, that's
    /your/ problem. Millions of others manage to use gcc for C programming.
    Start facing the reality that it is /you/ who is doing something
    wrong, not the rest of the world.


    ˙ Why would a compiler need to add a specific option for something
    that is rarely required and where there is a simple and fairly obvious
    common option ("-v", or "-- verbose") to get the information?

    That option is next to useless because it buries what you need in a
    mountain of junk.

    Not that you are exaggerating at all.


    On the other hand, slightly better code optimisation can mean longer
    battery life, smaller and cheaper hardware, or more functionality in
    my program.

    Maybe you do get it after all. Using smaller, simpler, faster tools
    gives all those advantages too.

    It's a shame you don't see language tools in the same light as some of
    your applications.


    And /why/ is it a shame? In all your endless posts, you have never
    given a reason why it should matter to me.


    --- 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 Thu Sep 17 17:15:14 2026
    On 17/09/2026 16:38, Waldek Hebisch wrote:
    David Brown <david.brown@hesbynett.no> wrote:
    On 17/09/2026 14:15, bart wrote:

    I got a lot more output than that. Then I noticed you said 'amongst
    other things'. So -v does not produce less output than --verbose!


    Yes. You might think it strange, but I only posted the relevant lines
    here. There were a total of 31 lines from that command - it was not
    difficult to spot the ones relevant to the include paths.

    On my C compiler I used to have an option -paths which listed all the
    include paths it would use.

    I'm surprised that gcc, amongst it 1000s of options, doesn't have a
    dedicated one for this.


    I've never needed to see the list of paths before - they are all
    entirely obvious and standard, and "just work". Why would a compiler
    need to add a specific option for something that is rarely required and
    where there is a simple and fairly obvious common option ("-v", or
    "--verbose") to get the information?

    For the benefit of configure scripts?

    Some people need to write configure scripts. I don't. I neither know
    nor care what people might want in such configure scripts, but I feel confident that if this was actually something that people needed to do
    on a regular basis, either such a flag would have been added to gcc, or someone would have published a simple recipe or script for getting the information out of gcc.

    What I wrote was that /I/ have never needed such a list of include
    paths. And /I/ do not find it difficult to spot them from the output of
    "gcc -v -E empty.c". Other people's experiences may vary. Bart
    apparently regularly needs to get the include paths from his own
    compiler, that he wrote, which seems strange to me.

    And for symmetry?

    Symmetry of what?

    I find
    options like:

    -print-search-dirs
    -print-multiarch
    ...
    -print-sysroot-headers-suffix

    but the last one apparently does not work in normal install (even
    for cross compilers), and the other seem to give no info about headers.


    <https://gcc.gnu.org/onlinedocs/gcc/Developer-Options.html>

    These options are about the way the compiler was configured when it was
    built. The manual page is "primarily of interest to GCC developers".

    It might look like these options are for showing include directory
    paths, but they are not.


    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From bart@3:633/10 to All on Thu Sep 17 16:46:16 2026
    On 17/09/2026 16:05, David Brown wrote:
    On 17/09/2026 16:25, bart wrote:
    On 17/09/2026 14:16, David Brown wrote:
    On 17/09/2026 14:15, bart wrote:
    On 17/09/2026 11:52, David Brown wrote:
    On 17/09/2026 02:49, bart wrote:
    Was there some installation process that put the headers in a place >>>>>>>> where gcc will look for it without being told? Does it involve >>>>>>>> using
    'pkg-config'?

    Yes, installing the Ubuntu package "libsdl2-dev" created and
    populated the /usr/include/SDL2 directory, among other things.
    That's a typical approach for Unix-like systems.

    pkg-config does know about sdl2, but "#include <SDL2/SDL.h>" appears >>>>>>> to work without invoking pkg-config.˙ There may be more to it than >>>>>>> that, but I don't use SDL so I haven't looked into it.

    I have no idea how you'd set it up on Windows, but ...

    And I've no idea where gcc would look for its headers, other than >>>>>> where it keeps its system headers, or how to set it up to look
    permanently in certain places.

    touch empty.c
    gcc -E -v empty.c

    That will show you, amongst other things, the default include
    paths. On my system, it shows :

    #include "..." search starts here:
    #include <...> search starts here:
    ˙˙/usr/lib/gcc/x86_64-linux-gnu/13/include
    ˙˙/usr/local/include
    ˙˙/usr/include/x86_64-linux-gnu
    ˙˙/usr/include
    End of search list.

    I got a lot more output than that. Then I noticed you said 'amongst
    other things'. So -v does not produce less output than --verbose!


    Yes.˙ You might think it strange, but I only posted the relevant
    lines here.˙ There were a total of 31 lines from that command - it
    was not difficult to spot the ones relevant to the include paths.

    Always making excuses for gcc! I get 37 lines from it, but because
    many are long and wrap, my screen shows over 85 lines, with 25 of them
    scrolling off the top of the window. It looks a mess.

    If gcc had a flag to show the include paths, and nothing but the include paths, you'd complain that you had to read through piles of
    documentation to find it.˙ It does not seem to matter what inane,
    pointless task you and you alone think is vital, your life seems to
    revolve around saying that gcc is bad in every way.˙ So what's next? gcc
    is a terrible tool because you find it harder to type "gcc" than "bcc" ?

    Sometimes you have sane points about weaknesses in C, or things that
    could be improved in gcc, clang, and other tools - or at least, they
    were sane points the first time you raised them rather than the
    hundredth time.

    Because I get bitten for the hundredth time.

    Oh, and does your fantastic OS not have scrollbars to see more lines of output?


    More mitigation. Do you ever stop giving excuses for poor software?

    Somebody needs some a few lines of info from a program, but the tool
    buries it in 1000 lines of output, and your suggestion is to just to
    scroll up and down trying to find it?

    Anything but fix the problem!

    ˙ Are you stuck with terminal windows limited to 80 characters
    wide, just like we all used last century?˙ Do you not know how to use
    the "less" command? (Oh, wait, "less" is only 42 years old - we could
    not expect Windows to have caught up with such basic tools in that time.
    ˙But you can use "more".)

    I mentioned in another post about Clang choosing to write error messages
    /in the same colour/ as my console background.

    It also likes to generate LOTS of messages. So scrolling here wouldn't help.

    gcc has its own problems: only the name of failing program is invisible,
    but for the rest, it annoying changes my background colour to black and
    does not restore it.

    You'd think major tools like these wouldn't be so brain-dead.

    It's not hard to do these checks and to restore original settings.

    (1) The list of locations that it will be looking

    (2) All the locations it's checked (this is not necessarily the
    ˙˙˙˙ same list; see my last post)


    Learn to use a computer for software development, and stop bleating when
    you actually have to lift a finger!˙ Of course I have occasionally had a compile fail because my code references a missing header.˙ When it
    happens I either find the header, or fix the typo in my code.˙ We are
    not doing brain surgery here.

    But if it there was a dedication option for it, you'd use it? Maybe that
    info can be listed at the same time it reports the missing header.

    See, creating a more friendly compiler is easy! But, no, it's better
    that a million programmers have to mess around even if it's not brain
    surgery.


    If you can't program in C, and can't use normal C compilers, that's /
    your/ problem.˙ Millions of others manage to use gcc for C programming.
    ˙Start facing the reality that it is /you/ who is doing something
    wrong, not the rest of the world.


    ˙ Why would a compiler need to add a specific option for something
    that is rarely required and where there is a simple and fairly
    obvious common option ("-v", or "-- verbose") to get the information?

    That option is next to useless because it buries what you need in a
    mountain of junk.

    Not that you are exaggerating at all.

    If I do 'gcc -v hello.c' it produces 6724 bytes of output (remember this
    is a mess of wrapped lines).

    The relevant info is 367 bytes of that, so about 95% of the output was irrelevant junk.

    Hardly exaggerating.



    --- 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 Thu Sep 17 16:33:11 2026
    David Brown <david.brown@hesbynett.no> wrote:
    On 17/09/2026 16:38, Waldek Hebisch wrote:
    David Brown <david.brown@hesbynett.no> wrote:
    On 17/09/2026 14:15, bart wrote:

    I got a lot more output than that. Then I noticed you said 'amongst
    other things'. So -v does not produce less output than --verbose!


    Yes. You might think it strange, but I only posted the relevant lines
    here. There were a total of 31 lines from that command - it was not
    difficult to spot the ones relevant to the include paths.

    On my C compiler I used to have an option -paths which listed all the
    include paths it would use.

    I'm surprised that gcc, amongst it 1000s of options, doesn't have a
    dedicated one for this.


    I've never needed to see the list of paths before - they are all
    entirely obvious and standard, and "just work". Why would a compiler
    need to add a specific option for something that is rarely required and
    where there is a simple and fairly obvious common option ("-v", or
    "--verbose") to get the information?

    For the benefit of configure scripts?

    Some people need to write configure scripts. I don't. I neither know
    nor care what people might want in such configure scripts, but I feel confident that if this was actually something that people needed to do
    on a regular basis, either such a flag would have been added to gcc, or someone would have published a simple recipe or script for getting the information out of gcc.

    The '-print-...' options appeared because people did not want to
    hardcode assumptions or do convolved tests. Having compiler print
    info that it knows is much easier. Lack of such option for
    include files means that there was no _pressing_ need, but not
    that there is no need at all.

    What I wrote was that /I/ have never needed such a list of include
    paths. And /I/ do not find it difficult to spot them from the output of "gcc -v -E empty.c". Other people's experiences may vary. Bart
    apparently regularly needs to get the include paths from his own
    compiler, that he wrote, which seems strange to me.

    And for symmetry?

    Symmetry of what?

    Symmetry of options. There are options to print various important
    info, but one piece, that is default include path is currently
    missing.

    I find
    options like:

    -print-search-dirs
    -print-multiarch
    ...
    -print-sysroot-headers-suffix

    but the last one apparently does not work in normal install (even
    for cross compilers), and the other seem to give no info about headers.


    <https://gcc.gnu.org/onlinedocs/gcc/Developer-Options.html>

    These options are about the way the compiler was configured when it was built. The manual page is "primarily of interest to GCC developers".

    It might look like these options are for showing include directory
    paths, but they are not.

    That is my point.

    --
    Waldek Hebisch

    --- 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 Thu Sep 17 20:22:45 2026
    On 17/09/2026 17:46, bart wrote:
    On 17/09/2026 16:05, David Brown wrote:
    On 17/09/2026 16:25, bart wrote:
    On 17/09/2026 14:16, David Brown wrote:
    On 17/09/2026 14:15, bart wrote:
    On 17/09/2026 11:52, David Brown wrote:
    On 17/09/2026 02:49, bart wrote:
    Was there some installation process that put the headers in a >>>>>>>>> place
    where gcc will look for it without being told? Does it involve >>>>>>>>> using
    'pkg-config'?

    Yes, installing the Ubuntu package "libsdl2-dev" created and
    populated the /usr/include/SDL2 directory, among other things. >>>>>>>> That's a typical approach for Unix-like systems.

    pkg-config does know about sdl2, but "#include <SDL2/SDL.h>"
    appears
    to work without invoking pkg-config.˙ There may be more to it than >>>>>>>> that, but I don't use SDL so I haven't looked into it.

    I have no idea how you'd set it up on Windows, but ...

    And I've no idea where gcc would look for its headers, other than >>>>>>> where it keeps its system headers, or how to set it up to look
    permanently in certain places.

    touch empty.c
    gcc -E -v empty.c

    That will show you, amongst other things, the default include
    paths. On my system, it shows :

    #include "..." search starts here:
    #include <...> search starts here:
    ˙˙/usr/lib/gcc/x86_64-linux-gnu/13/include
    ˙˙/usr/local/include
    ˙˙/usr/include/x86_64-linux-gnu
    ˙˙/usr/include
    End of search list.

    I got a lot more output than that. Then I noticed you said 'amongst >>>>> other things'. So -v does not produce less output than --verbose!


    Yes.˙ You might think it strange, but I only posted the relevant
    lines here.˙ There were a total of 31 lines from that command - it
    was not difficult to spot the ones relevant to the include paths.

    Always making excuses for gcc! I get 37 lines from it, but because
    many are long and wrap, my screen shows over 85 lines, with 25 of
    them scrolling off the top of the window. It looks a mess.

    If gcc had a flag to show the include paths, and nothing but the
    include paths, you'd complain that you had to read through piles of
    documentation to find it.˙ It does not seem to matter what inane,
    pointless task you and you alone think is vital, your life seems to
    revolve around saying that gcc is bad in every way.˙ So what's next?
    gcc is a terrible tool because you find it harder to type "gcc" than
    "bcc" ?

    Sometimes you have sane points about weaknesses in C, or things that
    could be improved in gcc, clang, and other tools - or at least, they
    were sane points the first time you raised them rather than the
    hundredth time.

    Because I get bitten for the hundredth time.

    Oh, and does your fantastic OS not have scrollbars to see more lines
    of output?


    More mitigation. Do you ever stop giving excuses for poor software?

    Somebody needs some a few lines of info from a program, but the tool
    buries it in 1000 lines of output, and your suggestion is to just to
    scroll up and down trying to find it?

    Anything but fix the problem!

    What ****ing problem? You are talking about something that virtually no
    C programmer ever bothers doing, and anyone who needs to ask their
    compiler about the include paths only ever needs to do so /once/. There
    were 31 lines - not a 1000 - and the relevant lines are blindingly
    obvious in the output. If it took you more than a second or two to spot
    them, you should get a better screen or a better pair of glasses. Get
    over your paranoia and your egoism - compiler vendors (and compiler
    users) are not all dedicated to causing you trouble, and they don't all
    have to revolve around trying to support whatever daft uses and misuses
    you want to make of their tools.


    ˙ Are you stuck with terminal windows limited to 80 characters wide,
    just like we all used last century?˙ Do you not know how to use the
    "less" command? (Oh, wait, "less" is only 42 years old - we could not
    expect Windows to have caught up with such basic tools in that time.
    ˙˙But you can use "more".)

    I mentioned in another post about Clang choosing to write error
    messages /in the same colour/ as my console background.

    If only there were a simple way to change these for people who don't
    like the defaults (which were probably picked to fit the extremely
    common choice of black background in terminal windows). If only there
    were a simple way to change the background colour of your console. If
    only there were a simple website that could help you find out how to
    change these colours by typing in a question, and copying out the
    answers it gives you. But no, you don't want answers, or help - you
    want to cry about how tools that are fine for countless other developers
    are not fine-tuned exactly to your personal preferences.

    And yes, I am being patronising - stop acting like a spoiled child, and
    I will stop being patronising.


    --- 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 Thu Sep 17 20:26:10 2026
    On 17/09/2026 18:33, Waldek Hebisch wrote:
    David Brown <david.brown@hesbynett.no> wrote:

    <https://gcc.gnu.org/onlinedocs/gcc/Developer-Options.html>

    These options are about the way the compiler was configured when it was
    built. The manual page is "primarily of interest to GCC developers".

    It might look like these options are for showing include directory
    paths, but they are not.

    That is my point.


    The options intended for use only by GCC developers are poorly named.
    Usually naming of that kind of thing is not a priority. What is
    unusual, as I see it, is that they are documented in the user-oriented reference manual, rather than the internals manual.



    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From bart@3:633/10 to All on Thu Sep 17 20:19:06 2026
    On 17/09/2026 19:22, David Brown wrote:
    On 17/09/2026 17:46, bart wrote:
    On 17/09/2026 16:05, David Brown wrote:
    On 17/09/2026 16:25, bart wrote:
    On 17/09/2026 14:16, David Brown wrote:
    On 17/09/2026 14:15, bart wrote:
    On 17/09/2026 11:52, David Brown wrote:
    On 17/09/2026 02:49, bart wrote:
    Was there some installation process that put the headers in a >>>>>>>>>> place
    where gcc will look for it without being told? Does it involve >>>>>>>>>> using
    'pkg-config'?

    Yes, installing the Ubuntu package "libsdl2-dev" created and >>>>>>>>> populated the /usr/include/SDL2 directory, among other things. >>>>>>>>> That's a typical approach for Unix-like systems.

    pkg-config does know about sdl2, but "#include <SDL2/SDL.h>" >>>>>>>>> appears
    to work without invoking pkg-config.˙ There may be more to it than >>>>>>>>> that, but I don't use SDL so I haven't looked into it.

    I have no idea how you'd set it up on Windows, but ...

    And I've no idea where gcc would look for its headers, other
    than where it keeps its system headers, or how to set it up to >>>>>>>> look permanently in certain places.

    touch empty.c
    gcc -E -v empty.c

    That will show you, amongst other things, the default include
    paths. On my system, it shows :

    #include "..." search starts here:
    #include <...> search starts here:
    ˙˙/usr/lib/gcc/x86_64-linux-gnu/13/include
    ˙˙/usr/local/include
    ˙˙/usr/include/x86_64-linux-gnu
    ˙˙/usr/include
    End of search list.

    I got a lot more output than that. Then I noticed you said
    'amongst other things'. So -v does not produce less output than -- >>>>>> verbose!


    Yes.˙ You might think it strange, but I only posted the relevant
    lines here.˙ There were a total of 31 lines from that command - it
    was not difficult to spot the ones relevant to the include paths.

    Always making excuses for gcc! I get 37 lines from it, but because
    many are long and wrap, my screen shows over 85 lines, with 25 of
    them scrolling off the top of the window. It looks a mess.

    If gcc had a flag to show the include paths, and nothing but the
    include paths, you'd complain that you had to read through piles of
    documentation to find it.˙ It does not seem to matter what inane,
    pointless task you and you alone think is vital, your life seems to
    revolve around saying that gcc is bad in every way.˙ So what's next?
    gcc is a terrible tool because you find it harder to type "gcc" than
    "bcc" ?

    Sometimes you have sane points about weaknesses in C, or things that
    could be improved in gcc, clang, and other tools - or at least, they
    were sane points the first time you raised them rather than the
    hundredth time.

    Because I get bitten for the hundredth time.

    Oh, and does your fantastic OS not have scrollbars to see more lines
    of output?


    More mitigation. Do you ever stop giving excuses for poor software?

    Somebody needs some a few lines of info from a program, but the tool
    buries it in 1000 lines of output, and your suggestion is to just to
    scroll up and down trying to find it?

    Anything but fix the problem!

    What ****ing problem?˙ You are talking about something that virtually no
    C programmer ever bothers doing, and anyone who needs to ask their
    compiler about the include paths only ever needs to do so /once/.˙ There were 31 lines - not a 1000

    There were 85 lines that scrolled up the screen.

    But if it was 1000, then so what: your suggestion to use the scrollbar
    would still work, yes?


    - and the relevant lines are blindingly
    obvious in the output.˙ If it took you more than a second or two to spot them, you should get a better screen or a better pair of glasses.

    That info is also presented appallingly. What's wrong with blank lines
    to separate the different sections?

    And what's with the super-long lines that are guaranteed to wrap? The
    two longest lines are 1700-1800 characters.

    It's a joke, seriously. My own diagnostics are better, but they would
    not be good enough for a professional product.


    ˙ Are you stuck with terminal windows limited to 80 characters wide,
    just like we all used last century?˙ Do you not know how to use the
    "less" command? (Oh, wait, "less" is only 42 years old - we could not
    expect Windows to have caught up with such basic tools in that time.
    ˙˙But you can use "more".)

    I mentioned in another post about Clang choosing to write error
    messages /in the same colour/ as my console background.

    If only there were a simple way to change these for people who don't
    like the defaults (which were probably picked to fit the extremely
    common choice of black background in terminal windows).˙ If only there
    were a simple way to change the background colour of your console.˙ If
    only there were a simple website that could help you find out how to
    change these colours by typing in a question, and copying out the
    answers it gives you.˙ But no, you don't want answers, or help - you
    want to cry about how tools that are fine for countless other developers
    are not fine-tuned exactly to your personal preferences.

    And yes, I am being patronising - stop acting like a spoiled child, and
    I will stop being patronising.


    And you continue making excuses for poor software.

    Are you seriously suggesting that, each time I run some console program,
    I should change my screen background colour in order to be able to see
    its messages? Each program make might choose a different colour!

    Or even that I have to investigate every such program to change its
    default colours? They should Just Work.

    It's a bug; not a serious one, it's more amusing/incredulous, but still
    a bug.

    If only there were a simple way to change the background colour

    If only there was a way of avoiding text that would inadvertently
    clashes with the screen background.

    want to cry about how tools that are fine for countless other developers

    By luck apparently; presumably they manage to avoid colour 0xC0C0C0 or something near for their background.

    People here are always on about making assumptions, so why assume a
    black background /in a system where the background colour can be chosen
    by the user/? The choice of light grey isn't that great for a white
    background either.



    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From tTh@3:633/10 to All on Thu Sep 17 21:31:45 2026
    On 9/17/26 17:46, bart wrote:

    Somebody needs some a few lines of info from a program, but the tool
    buries it in 1000 lines of output, and your suggestion is to just to
    scroll up and down trying to find it?

    Anything but fix the problem!

    May be you can code a patch who fix the^Wyour problem, and
    send it to the Gcc team ? Any positive contribution is
    benefit to all of us.

    --
    ** **
    * tTh des Bourtoulots *
    * http://maison.tth.netlib.re/ *
    ** **

    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From tTh@3:633/10 to All on Thu Sep 17 21:53:14 2026
    On 9/17/26 17:46, bart wrote:

    I mentioned in another post about Clang choosing to write error
    messages /in the same colour/ as my console background.

    $ some_command_who_change_color | cat

    problem solved.

    --
    ** **
    * tTh des Bourtoulots *
    * http://maison.tth.netlib.re/ *
    ** **

    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From bart@3:633/10 to All on Thu Sep 17 20:54:35 2026
    On 17/09/2026 20:31, tTh wrote:
    On 9/17/26 17:46, bart wrote:

    Somebody needs some a few lines of info from a program, but the tool
    buries it in 1000 lines of output, and your suggestion is to just to
    scroll up and down trying to find it?

    Anything but fix the problem!

    ˙˙ May be you can code a patch who fix the^Wyour problem, and
    ˙˙ send it to the Gcc team ? Any positive contribution is
    ˙˙ benefit to all of us.

    I'm not interested in gcc. I have my own solutions.

    This is just one more annoying thing about that program. The issue here
    is that nobody is daring to criticise its crass behaviours, while trying
    to deflect issues onto users.

    Its crassness starts here:

    c:\c>gcc
    gcc: fatal error: no input files
    compilation terminated.

    Most command-line compilers give you version and help info when no
    parameters follow. But at least it says something; try this:

    c:\c\as

    and it apparently hangs (it's waiting for you type an assembly program
    from the console!)

    How did programs which work like some student's crude first console app
    ever make it into the wild?

    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From tTh@3:633/10 to All on Thu Sep 17 21:55:02 2026
    On 9/17/26 21:19, bart wrote:
    And what's with the super-long lines that are guaranteed to wrap? The
    two longest lines are 1700-1800 characters.

    $ some_command_who_make_long_lines | fmt

    problem solved.

    --
    ** **
    * tTh des Bourtoulots *
    * http://maison.tth.netlib.re/ *
    ** **

    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From bart@3:633/10 to All on Thu Sep 17 21:05:36 2026
    On 17/09/2026 20:53, tTh wrote:
    On 9/17/26 17:46, bart wrote:

    I mentioned in another post about Clang choosing to write error
    messages /in the same colour/ as my console background.

    ˙˙ $ some_command_who_change_color | cat

    ˙˙˙˙˙˙˙˙˙˙˙˙˙ problem solved.


    You're deflecting again.

    It's not my product to fix; it should just work. Here's what happens
    when I type 'clang' in a console:

    https://github.com/bart-2026/langs/blob/main/clang.png

    I had to use a screen shot to capture it. What do you think the error says?

    Here's what happens when I type 'tcc':

    c:\c>tcc
    Tiny C Compiler 0.9.27 - Copyright (C) 2001-2006 Fabrice Bellard
    Usage: tcc [options...] [-o outfile] [-c] infile(s)...
    tcc [options...] -run infile [arguments...]
    General options:
    ...

    And yet people look down their nose at it!

    This is mine in action:

    c:\c>bcc
    BCC Compiler 7.x
    Usage:
    bcc prog[.c] Compile prog.c to prog.exe
    bcc -r prog[.c] Compile prog.c and run
    bcc -i prog[.c] Compile prog.c and interpret
    bcc -help Show all options

    And yet Clang can't even display a fucking error message.

    --- 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 Thu Sep 17 13:25:00 2026
    On 9/16/2026 4:59 PM, Keith Thompson wrote:
    bart <bc@freeuk.com> writes:
    On 16/09/2026 16:53, David Brown wrote:
    On 16/09/2026 16:20, bart wrote:
    Another advantage is that the header is a single file that is easy
    to use, copy, bundle etc. You don't need - I options.
    My test file contained a single line :
    ˙˙˙˙#include <SDL2/SDL.h>
    and compiled with
    ˙˙˙˙gcc -c test.c
    There are no -I options.

    Where is your SDL2 folder located relative to the current directory?

    On my system (Ubuntu 24.04), it's "/usr/include/SDL2". David's
    system is probably similar.

    Was there some installation process that put the headers in a place
    where gcc will look for it without being told? Does it involve using
    'pkg-config'?

    Yes, installing the Ubuntu package "libsdl2-dev" created and
    populated the /usr/include/SDL2 directory, among other things.
    That's a typical approach for Unix-like systems.

    pkg-config does know about sdl2, but "#include <SDL2/SDL.h>" appears
    to work without invoking pkg-config. There may be more to it than
    that, but I don't use SDL so I haven't looked into it.

    I have no idea how you'd set it up on Windows, but ...

    Well, fwiw, vcpkg:

    https://vcpkg.io/en/



    Mine is in the current directory (that is, ./SDL3 is a folder that
    contains the headers). gcc doesn't work without '-I.' on either OS:

    Did you set that up manually? If you had two projects that use SDL,
    would you have to create "./SDL3" folders in both of them?

    [...]



    --- 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 Thu Sep 17 13:26:01 2026
    On 9/16/2026 5:49 PM, bart wrote:
    [...]

    Give this a go:

    https://vcpkg.io



    --- 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 Thu Sep 17 15:06:57 2026
    bart <bc@freeuk.com> writes:
    On 17/09/2026 08:24, tTh wrote:
    On 9/17/26 02:49, bart wrote:
    And I've no idea where gcc would look for its headers, other than
    where it keeps its system headers, or how to set it up to look
    permanently in certain places.
    ˙˙ You just have to read the fscking manual.
    https://gcc.gnu.org/onlinedocs/gcc/Environment-Variables.html

    Nobody uses environment variables any more.

    Obviously untrue.

    In any case, none of those
    listed are set. So I still don't know how gcc even manages to find its
    own system headers. But I don't care.

    If you don't care, please stop talking about it. A lot of people,
    myself included, post here because they enjoy helping other people by
    answering questions and providing information and advice. If you say
    that you don't know something, people are going to waste their time
    trying to educate you.

    gcc on Windows is poor at this anyway: if I have two gcc versions
    installed, then they clash, and gcc.exe doesn't appear to use paths
    relative to itself to find its dependent binaries.

    I doubt that gcc is at fault for that, assuming it's true.
    gcc on Windows is typically installed as part of a larger package
    (since a compiler by itself can't generate executables). It's the responsibility of the gcc+FOO and gcc+BAR installers to arrange
    for their respecive gcc's to avoid conflicting with each other.
    Packaging gcc for Windows is more difficult than packaging gcc
    for Unix-like systems.

    ˙˙ But as everyone knows, learning new things isn't
    ˙˙ part of your philosophy...

    I don't care about individual compilers, especially gcc which is a
    PITA in working differently from other C compilers, apart from those
    which slavishly copy all it behaviours. Examples:

    You say you don't care about gcc. I don't think that's what you mean,
    given how much you talk about it.

    [57 lines deleted]

    So you can keep your stinkin' compiler.

    OK. Are we done?

    [116 lines deleted]

    --
    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 Keith Thompson@3:633/10 to All on Thu Sep 17 15:17:38 2026
    bart <bc@freeuk.com> writes:
    On 17/09/2026 13:51, David Brown wrote:
    On 17/09/2026 14:03, bart wrote:
    My gcc Windows installation (I went back to 14.2 as it includes
    clang), includes 3000 .h files. They can't all be for the standard
    library!

    As you well know, there is no such thing as a standard "gcc Windows"
    installation - there are multiple different packagings of gcc with
    different choices of libraries and other tools.˙ I am not sure it is
    going to be very helpful if you say exactly which Windows gcc
    installation you have, but there can be huge variations between
    them.

    If interested it was from winlibs.com. (The site looks like something
    from the 1990s but it has versions up 16.2.0.)

    I just looked at winlibs.com. WinLibs is a "standalone build of
    GCC and MinGW-w64 for Windows".

    You implied that those 3000 .h files were part of your gcc
    installation. In fact I'm nearly certain that most of them are
    part of MinGW-w64, which winlibs.com describes as "a free and open
    source C library for targetting Windows 32-bit and 64-bit platforms".

    Why do you continue to pretend not to understand that?

    [...]

    --
    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 Keith Thompson@3:633/10 to All on Thu Sep 17 15:24:21 2026
    bart <bc@freeuk.com> writes:
    [...]
    My gcc Windows installation (I went back to 14.2 as it includes
    clang), includes 3000 .h files.

    No it doesn't. As explained downthread, most of them are from
    MinGW-w64, which is packaged along with gcc by WinLibs (winlibs.com).

    They can't all be for the standard
    library!

    They aren't -- and gcc doesn't provide (most of) the standard library
    anyway. The "gcc" package does provide some .h files, some for internal
    use and some like stddef.h that are more closely tied to the compiler
    than to the library implementation.

    And 1200 .a archive files. So the approach there seems to be bundle
    headers and binaries for every possible library. But apparently not
    big ones like SDL.

    That's not "every possible library".

    Obviously MinGW-w64 includes *some* libraries. Obviously it doesn't
    include the SDL library. Obviously if you want to use SDL, you're
    expected to install it separately.

    [...]

    --
    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 Keith Thompson@3:633/10 to All on Thu Sep 17 15:44:48 2026
    bart <bc@freeuk.com> writes:
    [...]
    I'm not interested in gcc.

    Yes, you are.

    There are plenty of things I'm not interested in. I express my
    lack of interest by not talking about them. You talk about gcc a
    lot more than I do.

    Can you explain to us what you actually mean when you say you're
    "not interested in gcc"? And when you decide what you mean, can
    you start saying that rather than saying you're "not interested"?

    [...]

    --
    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 Scott Lurndal@3:633/10 to All on Thu Sep 17 23:47:34 2026
    bart <bc@freeuk.com> writes:
    On 17/09/2026 19:22, David Brown wrote:
    On 17/09/2026 17:46, bart wrote:
    On 17/09/2026 16:05, David Brown wrote:
    On 17/09/2026 16:25, bart wrote:
    On 17/09/2026 14:16, David Brown wrote:
    On 17/09/2026 14:15, bart wrote:
    On 17/09/2026 11:52, David Brown wrote:
    On 17/09/2026 02:49, bart wrote:
    Was there some installation process that put the headers in a >>>>>>>>>>> place
    where gcc will look for it without being told? Does it involve >>>>>>>>>>> using
    'pkg-config'?

    Yes, installing the Ubuntu package "libsdl2-dev" created and >>>>>>>>>> populated the /usr/include/SDL2 directory, among other things. >>>>>>>>>> That's a typical approach for Unix-like systems.

    pkg-config does know about sdl2, but "#include <SDL2/SDL.h>" >>>>>>>>>> appears
    to work without invoking pkg-config.˙ There may be more to it than >>>>>>>>>> that, but I don't use SDL so I haven't looked into it.

    I have no idea how you'd set it up on Windows, but ...

    And I've no idea where gcc would look for its headers, other >>>>>>>>> than where it keeps its system headers, or how to set it up to >>>>>>>>> look permanently in certain places.

    touch empty.c
    gcc -E -v empty.c

    That will show you, amongst other things, the default include >>>>>>>> paths. On my system, it shows :

    #include "..." search starts here:
    #include <...> search starts here:
    ˙˙/usr/lib/gcc/x86_64-linux-gnu/13/include
    ˙˙/usr/local/include
    ˙˙/usr/include/x86_64-linux-gnu
    ˙˙/usr/include
    End of search list.

    I got a lot more output than that. Then I noticed you said
    'amongst other things'. So -v does not produce less output than -- >>>>>>> verbose!


    Yes.˙ You might think it strange, but I only posted the relevant
    lines here.˙ There were a total of 31 lines from that command - it >>>>>> was not difficult to spot the ones relevant to the include paths.

    Always making excuses for gcc! I get 37 lines from it, but because
    many are long and wrap, my screen shows over 85 lines, with 25 of
    them scrolling off the top of the window. It looks a mess.

    If gcc had a flag to show the include paths, and nothing but the
    include paths, you'd complain that you had to read through piles of
    documentation to find it.˙ It does not seem to matter what inane,
    pointless task you and you alone think is vital, your life seems to
    revolve around saying that gcc is bad in every way.˙ So what's next?
    gcc is a terrible tool because you find it harder to type "gcc" than
    "bcc" ?

    Sometimes you have sane points about weaknesses in C, or things that
    could be improved in gcc, clang, and other tools - or at least, they
    were sane points the first time you raised them rather than the
    hundredth time.

    Because I get bitten for the hundredth time.

    Oh, and does your fantastic OS not have scrollbars to see more lines
    of output?


    More mitigation. Do you ever stop giving excuses for poor software?

    Somebody needs some a few lines of info from a program, but the tool
    buries it in 1000 lines of output, and your suggestion is to just to
    scroll up and down trying to find it?

    Anything but fix the problem!

    What ****ing problem?˙ You are talking about something that virtually no
    C programmer ever bothers doing, and anyone who needs to ask their
    compiler about the include paths only ever needs to do so /once/.˙ There
    were 31 lines - not a 1000

    There were 85 lines that scrolled up the screen.

    But if it was 1000, then so what: your suggestion to use the scrollbar
    would still work, yes?

    $ gcc -v -I. -I/root -E /tmp/e.c 2>&1 | grep "^ "
    /usr/libexec/gcc/x86_64-redhat-linux/4.8.3/cc1 -E -quiet -v -I . -I /root /tmp/e.c -mtune=generic -march=x86-64
    .
    /root
    /usr/lib/gcc/x86_64-redhat-linux/4.8.3/include
    /usr/local/include
    /usr/include

    --- 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 Thu Sep 17 23:48:41 2026
    bart <bc@freeuk.com> writes:
    On 17/09/2026 20:31, tTh wrote:
    On 9/17/26 17:46, bart wrote:

    Somebody needs some a few lines of info from a program, but the tool
    buries it in 1000 lines of output, and your suggestion is to just to
    scroll up and down trying to find it?

    Anything but fix the problem!

    ˙˙ May be you can code a patch who fix the^Wyour problem, and
    ˙˙ send it to the Gcc team ? Any positive contribution is
    ˙˙ benefit to all of us.

    I'm not interested in gcc. I have my own solutions.

    Then why do you keep harping on its purported defects?

    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Steven G. Kargl@3:633/10 to All on Fri Sep 18 00:04:22 2026
    On Thu, 17 Sep 2026 20:54:35 +0100, bart wrote:

    Most command-line compilers give you version and help info when no parameters follow. But at least it says something; try this:

    c:\c\as

    and it apparently hangs (it's waiting for you type an assembly program
    from the console!)


    Most people read (or at least skim) the documentation
    that comes with the software they use.

    % man as
    ...
    If you give 'as' no file names it attempts to read one
    input file from the 'as' standard input, which is normally
    your terminal. You may have to type ctl-D to tell 'as'
    there is no more program to assemble.

    HTH

    --
    steve

    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From bart@3:633/10 to All on Fri Sep 18 01:34:12 2026
    On 18/09/2026 01:04, Steven G. Kargl wrote:
    On Thu, 17 Sep 2026 20:54:35 +0100, bart wrote:

    Most command-line compilers give you version and help info when no
    parameters follow. But at least it says something; try this:

    c:\c\as

    and it apparently hangs (it's waiting for you type an assembly program
    from the console!)


    Most people read (or at least skim) the documentation
    that comes with the software they use.

    Most people probably don't. They will try running such programs without
    input, as often that gives usage info.

    'as' is more peculiar than most assemblers:

    * It takes input from stdin as default

    * The output, even on Windows, is a file called a.out

    * If given two or more input files, these are literally concatenated
    into one ASM file. More typically there is one object file produced per file


    % man as

    'man' doesn't exist on Windows. Using 'as --help' gives lots of
    complicated options that will mean little to some who has not used this
    before and simply wants to turn file.s into file.o.

    This is my assembler for example when I type its name:

    c:\c>aa
    AA7 Assembler 29-Aug-2026
    Usage:
    aa filename[.asm] # Assemble filename.asm to filename.exe
    aa -help # Show other options

    Simple, yes?





    If you give 'as' no file names it attempts to read one
    input file from the 'as' standard input, which is normally
    your terminal. You may have to type ctl-D to tell 'as'
    there is no more program to assemble.

    HTH



    --- 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 Thu Sep 17 17:50:57 2026
    bart <bc@freeuk.com> writes:
    On 18/09/2026 01:04, Steven G. Kargl wrote:
    [...]
    Most people read (or at least skim) the documentation
    that comes with the software they use.

    Most people probably don't. They will try running such programs
    without input, as often that gives usage info.

    [...]

    You've seen how that approach fails.

    There are valid reasons for the way "as" behaves. Your assumptions
    about how you think it *should* behave have led you astray.
    I suggest that it is your approach, not "as", that needs to change.

    Quick summary: You are trying to use tools that were originally
    designed to be used in a Unix-like environment, and expecting them
    to behave like native Windows tools.

    I'll explain further if you ask, but only if you convince me that
    you're actually interested in learning.

    --
    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 bart@3:633/10 to All on Fri Sep 18 02:04:12 2026
    On 17/09/2026 23:06, Keith Thompson wrote:
    bart <bc@freeuk.com> writes:
    On 17/09/2026 08:24, tTh wrote:
    On 9/17/26 02:49, bart wrote:
    And I've no idea where gcc would look for its headers, other than
    where it keeps its system headers, or how to set it up to look
    permanently in certain places.
    ˙˙ You just have to read the fscking manual.
    https://gcc.gnu.org/onlinedocs/gcc/Environment-Variables.html

    Nobody uses environment variables any more.

    Obviously untrue.

    Let's say they're out of fashion.

    gcc on Windows is poor at this anyway: if I have two gcc versions
    installed, then they clash, and gcc.exe doesn't appear to use paths
    relative to itself to find its dependent binaries.

    I doubt that gcc is at fault for that, assuming it's true.
    gcc on Windows is typically installed as part of a larger package
    (since a compiler by itself can't generate executables).

    I think the problem was that gcc runs support programs such as cc1.exe
    by relying on Windows to search the default paths.

    But if you have two versions A and B, and both their paths are listed in
    the PATH variable, then when B's gcc tries to run cc1.exe, it will be
    A's version, as A's path is listed first.

    It's the> responsibility of the gcc+FOO and gcc+BAR installers to arrange
    for their respecive gcc's to avoid conflicting with each other.
    Packaging gcc for Windows is more difficult than packaging gcc
    for Unix-like systems.

    It's not hard; it should really have used a path relative to B's gcc.exe.

    It would still pick A's gcc.exe if typing an unqualified 'gcc' by
    itself, but how does Linux solve this problem when you have two gcc's to choose from?


    ˙˙ But as everyone knows, learning new things isn't
    ˙˙ part of your philosophy...

    I don't care about individual compilers, especially gcc which is a
    PITA in working differently from other C compilers, apart from those
    which slavishly copy all it behaviours. Examples:

    You say you don't care about gcc. I don't think that's what you mean,
    given how much you talk about it.

    I don't care about having to give special treatment to different compilers.

    I only use three now (bcc, tcc, gcc), and gcc is a nuisance because of
    its stupid defaults.

    In this case I was investigating the impact of large headers across a codebase. The impact would likely be bigger on gcc because it is slower.

    I'm not that interested in gcc as a C compiler or in fixing it, but it
    is fascinating in how bad it is at many things and /that/ is interesting
    to me to discuss.

    Every single one of those things (other than build-speed) will have some option to fix it or to work around it if you dig enough, but I have no inclination to do that.

    I believe such tools should just work with the minimum of fuss.

    The sweetest of all is my own bcc, but that is the worst at supporting arbitrary C code, so sometimes I have to use another.

    So you can keep your stinkin' compiler.

    OK. Are we done?

    So, no comment on the fact that it can take three goes before gcc gets
    the DLL extension right? (It fact it never does; you have to specify it
    in the end. It seems to understand about 'exe' but is too stupid to know
    that -shared needs 'dll'.)
    [116 lines deleted]



    --- 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 Thu Sep 17 18:19:15 2026
    bart <bc@freeuk.com> writes:
    On 17/09/2026 23:06, Keith Thompson wrote:
    [...]
    You say you don't care about gcc. I don't think that's what you
    mean, given how much you talk about it.

    I don't care about having to give special treatment to different compilers.

    You obviously care very much about that.

    I think that when you say "I don't care about ...", you really mean
    "I don't like ...". You need to learn to communicate clearly.

    [...]

    So, no comment on the fact that it can take three goes before gcc gets
    the DLL extension right?
    [...]

    Correct. I have no comment on it because (a) it's not about the
    C programming language, the topic of this newsgroup, and (b) I do
    not care about it.

    --
    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 Johann "Myrkraverk" Oskarsson@3:633/10 to All on Fri Sep 18 10:17:33 2026
    On 9/10/2026 7:00 AM, fir wrote:
    Keith Thompson pisze:
    Janis Papanagnou <janis_papanagnou+ng@hotmail.com> writes:
    [...]
    (Please, for the sake of the people that haven't killfiled you, use an
    online-translator to create comprehensible texts! - In case that your
    native language *is* English I suggest to translate your text to some
    other language and then back to English; the translators are obviously
    good enough to fix your language or writing problems in that process.)

    The above was addressed to "fir".˙ As I recall, his native language
    is Polish.

    "fir" has been posting here for a long time.˙ Here's something our own
    David Brown wrote about him in 2015.˙ I can't directly vouch for its
    accuracy, but it seems plausible.

    ˙˙˙˙ He does not have dyslexia.˙ English is a second language for him,
    ˙˙˙˙ but he is capable of writing much better than he does (I have seen
    ˙˙˙˙ him do so) - he /intentionally/ writes in this manner because he
    ˙˙˙˙ considers himself too much of a grand thinker and philosopher to
    ˙˙˙˙ lower himself to our mere "commoner" language.˙ As far as I
    ˙˙˙˙ understand it, he writes in a similar manner in his own language.
    ˙˙˙˙ Many of us have tried to suggest he changes his manner for his own
    ˙˙˙˙ good as well as ours - but to no avail.

    Reference:

    ˙˙˙˙ Subject: Re: Recursion or loop, design questions
    ˙˙˙˙ Date: Wed, 05 Aug 2015 08:45:25 +0200
    ˙˙˙˙ Message-ID: <mpsbb5$3s9$1@dont-email.me>

    I suggest that one more attempt to get fir to write clearly is
    unlikely to be effective.˙ I've solved the problem for myself by
    adding him to my killfile.


    funny, honestly i dont know why i write such way as i write

    i suspect its in big extent becouse if i think on c language ideas im
    kina highly focused and 'turning' to think on all this letters is on
    kinda different plane so it annoys me, its hard to be focused on
    thinking on higher c topics and on editing sentences, translating text
    in google or chat gpt..its robably possible but so wearing that the
    oryginal thoughts would sufer too much

    i may say hovver i got some friends on some irc i used for years and
    they never complained for some reason..though i wrote in polish there
    and on chat you look on text much more than when you write messages on usenet

    I also find it funny, that when I write /clearly/ here in comp.lang.c,
    I get accused of being an L.L.M. This is apparently special for comp.
    lang.c, because I've received no such accusation in other Usenet groups.

    Also, I.R.C. users are probably more used to idiosyncratic text mess-
    ages, and therefore have no reason to /killfile/ you, just because they
    don't have enough reading comprehension to read what they decide is "bad English."

    At least, I have no problem understanding you.


    Best wishes, and happy forking 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 Johann "Myrkraverk" Oskarsson@3:633/10 to All on Fri Sep 18 10:23:40 2026
    On 9/10/2026 7:29 AM, Keith Thompson wrote:
    Lane W <cactus_DAC@yahoo.com> writes:
    fir wrote:
    [...]
    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?

    Please refrain from mentioning my name in any future posts. I have
    no interest in watching you embarrass yourself.

    I intend to add you to my killfile (technically, my Gnus scorefile),
    with the result that I will never see any of your posts here.
    If your embarrassing behavior improves in the next few days,
    I'll consider not doing so. To be clear, this is not a threat.
    It's simply something I intend to do to make my own experience here
    a little better, by giving me a view of comp.lang.c that does not
    include you. Others will do as they wish.


    Don't worry about Keith. He just thinks too highly of himself. It's
    much better to silently killfile people that to /threaten it/.


    Best wishes, and happy killfiling Keith!
    --
    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 Steven G. Kargl@3:633/10 to All on Fri Sep 18 05:42:33 2026
    On Fri, 18 Sep 2026 01:34:12 +0100, bart wrote:

    On 18/09/2026 01:04, Steven G. Kargl wrote:
    On Thu, 17 Sep 2026 20:54:35 +0100, bart wrote:

    Most command-line compilers give you version and help info when no
    parameters follow. But at least it says something; try this:

    c:\c\as

    and it apparently hangs (it's waiting for you type an assembly program
    from the console!)


    Most people read (or at least skim) the documentation
    that comes with the software they use.

    Most people probably don't.

    Touche. As a gfortran contributor, I'm well-aware of
    the fact that users lack reading abilities.

    They will try running such programs without
    input, as often that gives usage info.

    Not on a Unix(-like) system. Many tools will fall-back to accepting
    stdin for input. It's essentially how pipes on a command line
    work. May Microsoft doesn't know how to use pipes?

    'as' is more peculiar than most assemblers:

    * It takes input from stdin as default

    * The output, even on Windows, is a file called a.out

    * If given two or more input files, these are literally concatenated
    into one ASM file. More typically there is one object file produced per file


    % man as

    'man' doesn't exist on Windows.

    Well, this is your problem. Why are you using Window? :-)
    (and, no, linux is not the answer.)

    If 'man' doesn't exist on windows, google 'GNU as manual'.
    You might learn how to use the tool should work.

    Using 'as --help' gives lots of
    complicated options that will mean little to some who has not used this before and simply wants to turn file.s into file.o.

    This is my assembler for example when I type its name:

    c:\c>aa
    AA7 Assembler 29-Aug-2026
    Usage:
    aa filename[.asm] # Assemble filename.asm to filename.exe
    aa -help # Show other options

    Simple, yes?

    I suppose it's simply if one doesn't want to enter
    an assembly program at the command line.

    % as
    .text;
    .p2align 4,0x90;
    .globl sqrt;
    .type sqrt,@function;
    sqrt:;
    .cfi_startproc
    fldl 4(%esp)
    fsqrt
    ret
    .size sqrt, . - sqrt; .cfi_endproc

    .section .note.GNU-stack,"",%progbits
    % nm a.out
    0000000000000000 T sqrt

    or one can do

    % cat z.s
    .text;
    .p2align 4,0x90;
    .globl sqrt;
    .type sqrt,@function;
    sqrt:;
    .cfi_startproc
    fldl 4(%esp)
    fsqrt
    ret
    .size sqrt, . - sqrt; .cfi_endproc

    .section .note.GNU-stack,"",%progbits

    % cat z.s | as
    % nm a.out
    0000000000000000 T sqrt

    --
    steve


    --- 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 Fri Sep 18 08:08:31 2026
    On 2026-09-18 07:42, Steven G. Kargl wrote:
    On Fri, 18 Sep 2026 01:34:12 +0100, bart wrote:

    On 18/09/2026 01:04, Steven G. Kargl wrote:
    On Thu, 17 Sep 2026 20:54:35 +0100, bart wrote:

    Most command-line compilers give you version and help info when no
    parameters follow. But at least it says something; try this:

    c:\c\as

    and it apparently hangs (it's waiting for you type an assembly program >>>> from the console!)


    Most people read (or at least skim) the documentation
    that comes with the software they use.

    Most people probably don't.

    Touche. As a gfortran contributor, I'm well-aware of
    the fact that users lack reading abilities.

    They will try running such programs without
    input, as often that gives usage info.

    Not on a Unix(-like) system. Many tools will fall-back to accepting
    stdin for input. It's essentially how pipes on a command line
    work. May Microsoft doesn't know how to use pipes?

    'as' is more peculiar than most assemblers:

    * It takes input from stdin as default

    * The output, even on Windows, is a file called a.out

    * If given two or more input files, these are literally concatenated
    into one ASM file. More typically there is one object file produced per file >>

    % man as

    'man' doesn't exist on Windows.

    Well, this is your problem. Why are you using Window? :-)
    (and, no, linux is not the answer.)

    If 'man' doesn't exist on windows, google 'GNU as manual'.
    You might learn how to use the tool should work.

    Using 'as --help' gives lots of
    complicated options that will mean little to some who has not used this
    before and simply wants to turn file.s into file.o.

    This is my assembler for example when I type its name:

    c:\c>aa
    AA7 Assembler 29-Aug-2026
    Usage:
    aa filename[.asm] # Assemble filename.asm to filename.exe
    aa -help # Show other options

    Simple, yes?

    I suppose it's simply if one doesn't want to enter
    an assembly program at the command line.

    % as
    .text;
    .p2align 4,0x90;
    .globl sqrt;
    .type sqrt,@function;
    sqrt:;
    .cfi_startproc
    fldl 4(%esp)
    fsqrt
    ret
    .size sqrt, . - sqrt; .cfi_endproc

    .section .note.GNU-stack,"",%progbits
    % nm a.out
    0000000000000000 T sqrt

    or one can do

    % cat z.s
    .text;
    .p2align 4,0x90;
    .globl sqrt;
    .type sqrt,@function;
    sqrt:;
    .cfi_startproc
    fldl 4(%esp)
    fsqrt
    ret
    .size sqrt, . - sqrt; .cfi_endproc

    .section .note.GNU-stack,"",%progbits

    % cat z.s | as
    % nm a.out
    0000000000000000 T sqrt


    Note that it's unlikely (and thus IMO a bad example) that assembly code
    is entered on the command line.

    Note also that your pipe example is not convincing since if the program
    is already in a file ("z.s") you don't need a pipe.

    (BTW, you also don't need 'cat' in your example since "as < z.s" would
    suffice if you intend to use the standard input channel instead of a
    file.)

    I think a better explanation for 'as' accepting data from standard input
    would be the cases where some higher level languages create assembly
    data on standard output; as in "c-comp | as" or "pas-comp | as" .

    (But, probably most important for this thread; whatever we explain, the
    one you've been replying to is mentally resistant to such explanation
    as they don't fit his mental image and capabilities (or willingness) to
    think beyond.)

    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 Fri Sep 18 09:06:01 2026
    On 18/09/2026 00:24, Keith Thompson wrote:
    bart <bc@freeuk.com> writes:
    [...]
    My gcc Windows installation (I went back to 14.2 as it includes
    clang), includes 3000 .h files.

    No it doesn't. As explained downthread, most of them are from
    MinGW-w64, which is packaged along with gcc by WinLibs (winlibs.com).

    They can't all be for the standard
    library!

    They aren't -- and gcc doesn't provide (most of) the standard library
    anyway. The "gcc" package does provide some .h files, some for internal
    use and some like stddef.h that are more closely tied to the compiler
    than to the library implementation.


    While gcc does not provide a C standard library (as has been explained
    to Bart endlessly), the gcc team /do/ provide a C++ standard library.
    It is not part of the C compiler, but it is almost certainly also
    included in the "winlibs" package. And while the user-facing headers in
    the C++ standard library are mostly without extension, most of the
    internal headers are ".h" files. Thus a not insignificant part of those
    ".h" files he has were provided by gcc rather than third parties, but
    are not part of the C standard library.


    --- 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 Fri Sep 18 09:10:09 2026
    On 2026-09-15 12:53, David Brown wrote:
    On 15/09/2026 11:51, Janis Papanagnou wrote:
    [...]

    Right. - But don't forget that "spurious means" to tackle a topic is
    as well a source of obfuscating information; I certainly won't judge
    whether one or the other is in any (absolute or relative) way "better",
    but it certainly reminds me the recurring "if(a=5) vs. if(5=a)" debate
    to "ensure" "programming safety".

    [...]

    And we all know we should be writing "if (a == 5)", with decent spacing :-)

    Sure. Above was just a deliberate terse form for inline reference.
    Usually I'm using probably more spacing inline and between lines
    and chapters than the average programmer would find tolerable. ;-)


    Far more effective than any one developer changing their coding style
    would be having more warnings enabled by default in common compilers.
    (clang warns about "if (a = 5)" by default, while gcc needs "-Wall".
    Both warn about the misleading indentation only when warnings are enabled.)

    Yes, things have gotten much better since the dates back then when
    I did my professional programming in C/C++.


    Sure. - The point is; is there an objectively safe style here?
    I think there's subjective styles that helps some and annoys others.


    I have no statistics or reports to back up anything I say, so I can only
    say that I would /expect/ to see a small but measurable reduction in
    code errors if "indent without braces" conditionals are not allowed in
    code, if one were to compare code samples that had not used appropriate static checks.˙ That is, I /believe/ there is a objective difference
    here.˙ But I certainly can't claim to /know/ that there is.˙ And even if statistics bear me out here (maybe some PhD student has done the
    research), that would still not contradict your statement.˙ It is
    entirely reasonable to suppose that the style choices here would reduce risks for some programmers while making no difference to others - and no
    one likes being told to change their style without good reason.

    Actually, we established coding standards, and not following these
    required(!) - by those same standards - any deviation to be explained.

    (BTW, I authored, co-authored, and reviewed coding standard for three
    different programming languages; one of the rules - and contrary to my
    own convenience - was to always use braces also in the cases discussed!
    Just note that I haven't formulated it because one would be safer than
    the other; but we had to choose one option, and the rule to "always use
    braces" is just simpler (more practicable and easier to memorize) than
    an also sensible but very differentiated rule option - remember these
    simple 'if' cascades.)


    I don't think it makes sense to argue about that. (Especially given
    that we both have many decades of experience in the area.)


    This also makes it difficult to judge.˙ I am confident that any choice
    of style here would make no difference to the risk of errors in either
    your code or my code - we both know how to use "-Wall" and pay attention
    to the warnings, so if we /did/ make a mistake, our tools would tell us.

    You might be astonished but I don't recall to have needed any explicit
    warnings setting; our policy was a zero-warning approach (by the default warnings of our compilers), and where we identified any needs beyond we communicated with the build-management to make it the company default.
    Having good programmers, providing trainings and courses, helped also.

    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 Fri Sep 18 09:29:36 2026
    Johann "Myrkraverk" Oskarsson pisze:
    On 9/10/2026 7:00 AM, fir wrote:
    Keith Thompson pisze:
    Janis Papanagnou <janis_papanagnou+ng@hotmail.com> writes:
    [...]
    (Please, for the sake of the people that haven't killfiled you, use an >>>> online-translator to create comprehensible texts! - In case that your
    native language *is* English I suggest to translate your text to some
    other language and then back to English; the translators are obviously >>>> good enough to fix your language or writing problems in that process.)

    The above was addressed to "fir".˙ As I recall, his native language
    is Polish.

    "fir" has been posting here for a long time.˙ Here's something our own
    David Brown wrote about him in 2015.˙ I can't directly vouch for its
    accuracy, but it seems plausible.

    ˙˙˙˙ He does not have dyslexia.˙ English is a second language for him,
    ˙˙˙˙ but he is capable of writing much better than he does (I have seen
    ˙˙˙˙ him do so) - he /intentionally/ writes in this manner because he
    ˙˙˙˙ considers himself too much of a grand thinker and philosopher to
    ˙˙˙˙ lower himself to our mere "commoner" language.˙ As far as I
    ˙˙˙˙ understand it, he writes in a similar manner in his own language.
    ˙˙˙˙ Many of us have tried to suggest he changes his manner for his own
    ˙˙˙˙ good as well as ours - but to no avail.

    Reference:

    ˙˙˙˙ Subject: Re: Recursion or loop, design questions
    ˙˙˙˙ Date: Wed, 05 Aug 2015 08:45:25 +0200
    ˙˙˙˙ Message-ID: <mpsbb5$3s9$1@dont-email.me>

    I suggest that one more attempt to get fir to write clearly is
    unlikely to be effective.˙ I've solved the problem for myself by
    adding him to my killfile.


    funny, honestly i dont know why i write such way as i write

    i suspect its in big extent becouse if i think on c language ideas im
    kina highly focused and 'turning' to think on all this letters is on
    kinda different plane so it annoys me, its hard to be focused on
    thinking on higher c topics and on editing sentences, translating text
    in google or chat gpt..its robably possible but so wearing that the
    oryginal thoughts would sufer too much

    i may say hovver i got some friends on some irc i used for years and
    they never complained for some reason..though i wrote in polish there
    and on chat you look on text much more than when you write messages on
    usenet

    I also find it funny, that when I write /clearly/ here in comp.lang.c,
    I get accused of being an L.L.M.˙ This is apparently special for comp. lang.c, because I've received no such accusation in other Usenet groups.

    Also, I.R.C. users are probably more used to idiosyncratic text mess-
    ages, and therefore have no reason to /killfile/ you, just because they
    don't have enough reading comprehension to read what they decide is "bad English."

    At least, I have no problem understanding you.


    in most cases i think it may be understood but sometimes if i read my
    post some words i dont understand

    this is becouse of unfortunate typos, but i write a big amounts of
    posts and if iwould carefully read it all before osting i couldnt focus

    (so its eventually better to write is as a stream of thought and then
    post errata to it)



    Best wishes, and happy forking C!

    i wouldnt like to fork but i consider this situation that you have

    1) oryginal C and B (parts of it you could name as 'shallow' c, though
    og c is not shallow but some of its things seen by some people
    who dont try to see deeper may constitute shallow c shore)

    2) there is deeper deep c of various posibilities (which is maybe open,
    i mean you maybe cant just finish that coz this posibilities maybe are
    just not limited (i dont know)

    3) and there is ? which is maybe kinda arbitrary conglomerate but based
    on some diving in this theoretical deep c




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

    if those patterns are typical like by this insane oop crowd im not
    interesyed, im interested in more algebraical concise solutions only

    --- 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 Fri Sep 18 02:08:21 2026
    David Brown <david.brown@hesbynett.no> writes:
    On 18/09/2026 00:24, Keith Thompson wrote:
    [...]
    They aren't -- and gcc doesn't provide (most of) the standard library
    anyway. The "gcc" package does provide some .h files, some for
    internal use and some like stddef.h that are more closely tied to the
    compiler than to the library implementation.

    While gcc does not provide a C standard library (as has been explained
    to Bart endlessly), the gcc team /do/ provide a C++ standard
    library. It is not part of the C compiler, but it is almost certainly
    also included in the "winlibs" package. And while the user-facing
    headers in the C++ standard library are mostly without extension, most
    of the internal headers are ".h" files. Thus a not insignificant part
    of those ".h" files he has were provided by gcc rather than third
    parties, but are not part of the C standard library.

    Good point.

    I've said a number of times that "gcc" is a compiler, not a full C implementation. It's worth pointing out that the software package
    called "gcc" (downloadable in source form from gcc.gnu.org) does
    include some other software in addition to the compiler, including
    a small part of the library implementation for C and a much larger
    part of the library implementation for C++.

    OS-specific installers can and often do break this up into multiple
    installable packages. For example, on Ubuntu and related systems,
    the GNU compilers for various languages (C, C++, Fortran, Cobol,
    Ada, et al) are in separate packages, as are the headers and code.

    I have oversimplified this in the past.

    Having said all that, it is absolutely not the case that the bulk
    of the C standard library implementation is part of "gcc", however
    much a certain poster here pretends to believe that it is.

    --
    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 bart@3:633/10 to All on Fri Sep 18 10:23:48 2026
    On 18/09/2026 06:42, Steven G. Kargl wrote:
    On Fri, 18 Sep 2026 01:34:12 +0100, bart wrote:

    This is my assembler for example when I type its name:

    c:\c>aa
    AA7 Assembler 29-Aug-2026
    Usage:
    aa filename[.asm] # Assemble filename.asm to filename.exe
    aa -help # Show other options

    Simple, yes?

    I suppose it's simply if one doesn't want to enter
    an assembly program at the command line.

    Why do that when you can just use a text editor first? The chances are
    there will be errors and typos and then you just edit the file; how do
    you edit?

    Do you routinely type C code that way?

    And then, what happens to the source code of that program; is it just lost?

    If 'as' accepts stdin input then it will be primarily to support piping
    where the asm source has been machine-generated.

    Most command-line language tools that take in source will use text files
    as input.

    % as
    .text;
    .p2align 4,0x90;
    .globl sqrt;
    .type sqrt,@function;
    sqrt:;
    .cfi_startproc
    fldl 4(%esp)
    fsqrt
    ret
    .size sqrt, . - sqrt; .cfi_endproc

    .section .note.GNU-stack,"",%progbits

    Here's my version (this is for x64 using XMM regs on Win64 ABI, with a
    'main' routine to call it):

    sqrt::
    sqrtsd xmm0, xmm0
    ret

    main::
    sub rsp, 40

    mov xmm0, [two]
    call sqrt

    mov xmm1, xmm0
    movq rdx, xmm0
    mov rcx, fmt
    call printf*

    add rsp, 40
    ret

    isegment
    two:
    dq 2.0
    fmt:
    db "%f", 0

    This is my assembler in action:

    c:\ax>aa -r test
    Assembling test.asm to test.(run)
    1.414214

    The -r tells it to run the program immediately. Otherwise it generates
    an executable:

    c:\ax>aa test
    Assembling test.asm to test.exe
    c:\ax>test
    1.414214

    Notice I only had to type two 'aa test'; I don't even need the
    extension. 'aa' is super-smart and knows it is an assembler!

    With 'as', and with a version in GAS format, I'd need to do:

    as test.asm -o test.obj && gcc test.obj -o test

    This produces a 53KB file (18KB if I add -s). The aa version is 2.5KB.

    You can see that my versions, both assembly source and how it is
    invoked, are much cleaner and simpler. ('aa' does not need a linker.)



    --- 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 Fri Sep 18 11:27:02 2026
    On 18/09/2026 03:04, bart wrote:
    On 17/09/2026 23:06, Keith Thompson wrote:
    bart <bc@freeuk.com> writes:
    On 17/09/2026 08:24, tTh wrote:
    On 9/17/26 02:49, bart wrote:
    And I've no idea where gcc would look for its headers, other than
    where it keeps its system headers, or how to set it up to look
    permanently in certain places.
    ˙ ˙˙ You just have to read the fscking manual.
    https://gcc.gnu.org/onlinedocs/gcc/Environment-Variables.html

    Nobody uses environment variables any more.

    Obviously untrue.

    Let's say they're out of fashion.

    Let's not. Lots of people use them for various purposes.

    It is fair to say that Windows makes it a lot more of a hassle to make "permanent" changes to environment variables than *nix systems (or
    things like a "msys2 terminal" on Windows). And it is fair to say that
    some modern computer users can't cope with actually /typing/ something,
    rather than clicking on a box somewhere. But other people who like to
    have their computer and programs work the way they want them to, /do/
    set environment variables in various ways and circumstances -
    "permanent" changes in their .bashrc files (or Windows settings), or
    local changes in scripts, command aliases, prefixes to commands,
    makefiles, whatever.

    For example, I found some of the coloured output of "grep" difficult to
    read with the background colour I use in my terminals. I considered
    writing multiple posts in this group about how inconsiderate the "grep" authors are and how their bloated tool doesn't even look nice on my
    system. But in the end I decided to google for "change grep colours" as
    a short-cut for looking up the syntax, and a few minutes later I had a
    line in my .bashrc file with an environment variable to give grep
    colours that suited me better.


    gcc on Windows is poor at this anyway: if I have two gcc versions
    installed, then they clash, and gcc.exe doesn't appear to use paths
    relative to itself to find its dependent binaries.

    I doubt that gcc is at fault for that, assuming it's true.
    gcc on Windows is typically installed as part of a larger package
    (since a compiler by itself can't generate executables).

    I think the problem was that gcc runs support programs such as cc1.exe
    by relying on Windows to search the default paths.

    But if you have two versions A and B, and both their paths are listed in
    the PATH variable, then when B's gcc tries to run cc1.exe, it will be
    A's version, as A's path is listed first.

    It is conceivable that the folks behind this "winlib" packaging are
    idiots. But assuming they are not, then "cc1.exe" will not be in your
    path. The gcc driver program finds the additional parts in a path
    dependent on the way it was configured when built.

    When I type "gcc" on my machine, this finds /usr/bin/gcc. That file is
    a symbolic link pointing to "gcc-13", thus /usr/bin/gcc-13. That is
    also a symbolic link, pointing to the real gcc driver program called x86_64-linux-gnu-gcc-13. (The prefix here is a standard gcc name
    triplet with the target, OS and ABI.)

    When the program "x86_64-linux-gnu-gcc-13" wants to run "cc1", it finds
    it in the path ../libexec/gcc/x86_64-linux-gnu-gcc/13/.

    This way, the four different versions of native gcc that I have all find
    their own matching sub-programs, libraries, etc.

    Builds of gcc can have different configurations. Another Linux distro
    might build their gcc packages so that instead of using just 13 as the
    version number, they have 13.3.0. That would be useful if you wanted to
    have more than one gcc version 13.x.y installed at the same time - a
    level of detail that most users, and most distros, don't bother with.
    (For embedded cross-compilers, it's a different matter and precise
    revisions are important.)

    I don't know how "winlib" does their gcc configuration, or what (if any)
    path modifications its installer makes. Clearly it can't use exactly
    the same system as I described for Linux, because Windows doesn't
    support symbolic links. But if its installer changes your path to add
    the directory containing "cc1.exe", or puts "cc1.exe" in the same
    directory as your gcc, then it is doing things wrong and you should file
    that as a major bug in "winlib".



    It's the> responsibility of the gcc+FOO and gcc+BAR installers to
    arrange
    for their respecive gcc's to avoid conflicting with each other.
    Packaging gcc for Windows is more difficult than packaging gcc
    for Unix-like systems.

    It's not hard; it should really have used a path relative to B's gcc.exe.


    That is what gcc does, yes.

    It would still pick A's gcc.exe if typing an unqualified 'gcc' by
    itself, but how does Linux solve this problem when you have two gcc's to choose from?

    If I want gcc version 12, I use "gcc-12". If I want gcc version 14, I
    use "gcc-14". "gcc-13" is the standard gcc version for the particular
    version of the particular distro that I have on my work PC at the
    moment, so that is what I get with "gcc". The process by which the
    correct "cc1" is found is explained above.

    For other gcc's that are not native and part of the distro, I have the toolchains installed in individual directories, and refer to them by
    path, such as :

    /opt/arm-gnu-toolchain-15.2.rel1-x86_64-arm-none-eabi/bin/arm-none-eabi-gcc

    Of the path is given just once as a variable in my makefiles, so I don't
    have to specify it when building projects - and each project uses the
    version of gcc (and libraries) picked for the project.



    --- 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 Fri Sep 18 11:37:11 2026
    On 18/09/2026 09:10, Janis Papanagnou wrote:
    On 2026-09-15 12:53, David Brown wrote:
    On 15/09/2026 11:51, Janis Papanagnou wrote:
    [...]

    Right. - But don't forget that "spurious means" to tackle a topic is
    as well a source of obfuscating information; I certainly won't judge
    whether one or the other is in any (absolute or relative) way "better",
    but it certainly reminds me the recurring "if(a=5) vs. if(5=a)" debate
    to "ensure" "programming safety".

    [...]

    And we all know we should be writing "if (a == 5)", with decent
    spacing :-)

    Sure. Above was just a deliberate terse form for inline reference.
    Usually I'm using probably more spacing inline and between lines
    and chapters than the average programmer would find tolerable. ;-)

    I like space - it aids legibility. There's a reason the biggest key on
    the keyboard is the spacebar, and the second biggest is the return key.



    Far more effective than any one developer changing their coding style
    would be having more warnings enabled by default in common compilers.
    (clang warns about "if (a = 5)" by default, while gcc needs "-Wall".
    Both warn about the misleading indentation only when warnings are
    enabled.)

    Yes, things have gotten much better since the dates back then when
    I did my professional programming in C/C++.


    Tools have certainly got better, but the default warnings in compilers progress much too slowly IMHO. (Of course I can enable all the warning
    flags I like for my own use - but I'd prefer if everyone else used them
    more!)


    Sure. - The point is; is there an objectively safe style here?
    I think there's subjective styles that helps some and annoys others.


    I have no statistics or reports to back up anything I say, so I can
    only say that I would /expect/ to see a small but measurable reduction
    in code errors if "indent without braces" conditionals are not allowed
    in code, if one were to compare code samples that had not used
    appropriate static checks.˙ That is, I /believe/ there is a objective
    difference here.˙ But I certainly can't claim to /know/ that there
    is.˙ And even if statistics bear me out here (maybe some PhD student
    has done the research), that would still not contradict your
    statement.˙ It is entirely reasonable to suppose that the style
    choices here would reduce risks for some programmers while making no
    difference to others - and no one likes being told to change their
    style without good reason.

    Actually, we established coding standards, and not following these required(!) - by those same standards - any deviation to be explained.

    (BTW, I authored, co-authored, and reviewed coding standard for three different programming languages; one of the rules - and contrary to my
    own convenience - was to always use braces also in the cases discussed!
    Just note that I haven't formulated it because one would be safer than
    the other; but we had to choose one option, and the rule to "always use braces" is just simpler (more practicable and easier to memorize) than
    an also sensible but very differentiated rule option - remember these
    simple 'if' cascades.)

    That makes sense. Coding standard rules can never be the "best" for all circumstances and all users - even if people could agree what "best"
    means. They are always a compromise of sorts.



    I don't think it makes sense to argue about that. (Especially given
    that we both have many decades of experience in the area.)


    This also makes it difficult to judge.˙ I am confident that any choice
    of style here would make no difference to the risk of errors in either
    your code or my code - we both know how to use "-Wall" and pay
    attention to the warnings, so if we /did/ make a mistake, our tools
    would tell us.

    You might be astonished but I don't recall to have needed any explicit warnings setting; our policy was a zero-warning approach (by the default warnings of our compilers), and where we identified any needs beyond we communicated with the build-management to make it the company default.
    Having good programmers, providing trainings and courses, helped also.


    If the default warnings for your compiler matched something like "-Wall"
    in gcc, then that could be a good starting point. I don't know what compiler(s) you used, but for many IME the default warnings are pretty
    feeble. But it can certainly be impractical to insist on a specific
    list of different warning options, especially when a project includes third-party code that might have different conventions.




    --- 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 Fri Sep 18 17:42:58 2026
    On 18/09/2026 3:38 PM, fir wrote:
    Johann 'Myrkraverk' Oskarsson pisze:
    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.

    if those patterns are typical like by this insane oop crowd im not interesyed, im interested in more algebraical concise˙ solutions only

    Tornhill makes it quite clear that while the original /gang of four/
    patterns were phrased and presented in terms of OOP, his patterns are
    /not OOP/. You don't need classes to use Tornhill's patterns.

    He does use the same names for them, I believe; it's been quite a while
    since I read the original /Design Patterns/ book. This is both good and
    bad, because if you know what pattern you want to apply to C code, you
    can just look it up by the name in his book. It's bad because -- well
    he explains it better than I can in a summary. It's best you just read
    his words on the nomenclature.


    Best wishes, and happy reading C books!
    --
    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 Fri Sep 18 11:01:16 2026
    On 18/09/2026 10:08, Keith Thompson wrote:
    David Brown <david.brown@hesbynett.no> writes:


    I've said a number of times that "gcc" is a compiler, not a full C implementation. It's worth pointing out that the software package
    called "gcc" (downloadable in source form from gcc.gnu.org) does
    include some other software in addition to the compiler, including
    a small part of the library implementation for C and a much larger
    part of the library implementation for C++.

    OS-specific installers can and often do break this up into multiple installable packages. For example, on Ubuntu and related systems,
    the GNU compilers for various languages (C, C++, Fortran, Cobol,
    Ada, et al) are in separate packages, as are the headers and code.

    I have oversimplified this in the past.

    Having said all that, it is absolutely not the case that the bulk
    of the C standard library implementation is part of "gcc", however
    much a certain poster here pretends to believe that it is.

    Yes, we all know that 'gcc' is different. That seems to be its thing.

    Anyone who installs a C compiler for Windows expects to get everything necessary to compile C programs that use the standard library, into an executable.

    They couldn't care less how that is done, or whether, technically, the
    package they're using is a 'compiler', or 'compiler' plus other
    components. Or who or what provides the C library.

    If they choose 'gcc', then the picture is more complicated, but the end
    result is the same: they can compile those same programs and it just works.

    I've never understood what MingGW is about, and frankly don't care.
    Wherever you get gcc from, it always comes with some big bunch of stuff.

    But I /can/ tell you exactly how my own C implementation for Windows
    works. It comprises these three files:

    bcc.exe 328KB
    windows.h 608KB
    aa6.exe 116KB

    bcc is the main compiler that can directly write EXE/DLL/OBJ/ASM, or it
    can run programs directly as native code or by interpreting.

    It incorporates the standard headers. windows.h is separate as it would
    have made bcc.exe three times the size.

    For the C library it uses Windows' msvcrt.dll, dynamically linked (700KB).

    (This 'bcc' version only supports one C input file at a time, as it
    shares a back-end with my other, whole-program compiler.

    For multi-module C programs, bcc must generate ASM files which are
    assembled by aa6.exe into EXE etc. But 99% of bcc invocations are for
    single file programs.)

    You're welcome to explain gcc in the same way. You don't need to list
    /all/ the constituent files!


    --- 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 Fri Sep 18 03:05:09 2026
    bart <bc@freeuk.com> writes:
    [...]
    But I /can/ tell you exactly how my own C implementation for Windows
    works.

    But I don't care.

    --
    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 bart@3:633/10 to All on Fri Sep 18 11:13:38 2026
    On 18/09/2026 11:05, Keith Thompson wrote:
    bart <bc@freeuk.com> writes:
    [...]
    But I /can/ tell you exactly how my own C implementation for Windows
    works.

    But I don't care.



    Sure, you don't care how simple it is and how easy to give the whole
    picture of how it works. Or how, knowing that picture, anyone can see
    how they can install or copy this compiler anywhere.

    Or how much easier it is to see where the lines are: the implementation
    owns its standard headers, not the OS. And the OS provides the C library.

    This simplicity and transparency is by design.

    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From bart@3:633/10 to All on Fri Sep 18 11:21:10 2026
    On 18/09/2026 10:27, David Brown wrote:
    On 18/09/2026 03:04, bart wrote:

    But if you have two versions A and B, and both their paths are listed
    in the PATH variable, then when B's gcc tries to run cc1.exe, it will
    be A's version, as A's path is listed first.

    It is conceivable that the folks behind this "winlib" packaging are
    idiots.˙ But assuming they are not, then "cc1.exe" will not be in your
    path.˙ The gcc driver program finds the additional parts in a path
    dependent on the way it was configured when built.

    I've just tried two WINLIBS gcc versions, and now they work fine, if you
    use an explicit path to their respective gcc.exe files.

    The issue may have been with TDM distributions that I used to use. But
    WINLIBS has newer gcc versions.



    --- 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 Fri Sep 18 13:11:01 2026
    On 17/09/2026 21:54, bart wrote:
    On 17/09/2026 20:31, tTh wrote:
    On 9/17/26 17:46, bart wrote:

    Somebody needs some a few lines of info from a program, but the tool
    buries it in 1000 lines of output, and your suggestion is to just to
    scroll up and down trying to find it?

    Anything but fix the problem!

    ˙˙˙ May be you can code a patch who fix the^Wyour problem, and
    ˙˙˙ send it to the Gcc team ? Any positive contribution is
    ˙˙˙ benefit to all of us.

    I'm not interested in gcc. I have my own solutions.

    This is just one more annoying thing about that program. The issue here
    is that nobody is daring to criticise its crass behaviours, while trying
    to deflect issues onto users.

    Its crassness starts here:

    ˙ c:\c>gcc
    ˙ gcc: fatal error: no input files
    ˙ compilation terminated.


    Simple, clear, and to-the-point.

    Most command-line compilers give you version and help info when no parameters follow.

    Some do, some do not.

    Most command-line tools - gcc included - give you version information if
    you write "gcc --version", and help if you give "gcc --help".

    But at least it says something; try this:

    ˙ c:\c\as

    and it apparently hangs (it's waiting for you type an assembly program
    from the console!)

    Many programs can work as pipes. It is waiting for input from stdin,
    not particularly from the console. Programs that often get their input directly from other programs work this way.


    How did programs which work like some student's crude first console app
    ever make it into the wild?

    Perhaps it is because the developers know how to write programs designed
    to do useful jobs in a way that is convenient and efficient for the
    tasks they actually have to do? Maybe the developers of "as" expected
    users to have a clue about what they are doing?



    --- 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 Fri Sep 18 13:17:21 2026
    On 18/09/2026 12:21, bart wrote:
    On 18/09/2026 10:27, David Brown wrote:
    On 18/09/2026 03:04, bart wrote:

    But if you have two versions A and B, and both their paths are listed
    in the PATH variable, then when B's gcc tries to run cc1.exe, it will
    be A's version, as A's path is listed first.

    It is conceivable that the folks behind this "winlib" packaging are
    idiots.˙ But assuming they are not, then "cc1.exe" will not be in your
    path.˙ The gcc driver program finds the additional parts in a path
    dependent on the way it was configured when built.

    I've just tried two WINLIBS gcc versions, and now they work fine, if you
    use an explicit path to their respective gcc.exe files.

    The issue may have been with TDM distributions that I used to use. But WINLIBS has newer gcc versions.



    That is useful to know if I ever feel the need to have a newer gcc
    version on Windows. (It's unlikely, as these days I use my sole Windows machine so rarely I don't even have it connected to a screen and
    keyboard, but it is not impossible.)


    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Dan Cross@3:633/10 to All on Fri Sep 18 12:55:11 2026
    In article <118i2mc$q9l1$1@dont-email.me>, bart <bc@freeuk.com> wrote:
    On 17/09/2026 23:06, Keith Thompson wrote:
    bart <bc@freeuk.com> writes:
    On 17/09/2026 08:24, tTh wrote:
    On 9/17/26 02:49, bart wrote:
    And I've no idea where gcc would look for its headers, other than
    where it keeps its system headers, or how to set it up to look
    permanently in certain places.
    ˙˙ You just have to read the fscking manual.
    https://gcc.gnu.org/onlinedocs/gcc/Environment-Variables.html

    Nobody uses environment variables any more.

    Obviously untrue.

    Let's say they're out of fashion.

    Why would you say such a thing? While they may not be the most
    elegant solution to a number of problems, they're very much in
    use, and "in fashion", at least on Unix-derived systems.

    - Dan C.


    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From bart@3:633/10 to All on Fri Sep 18 14:03:00 2026
    On 18/09/2026 12:11, David Brown wrote:
    On 17/09/2026 21:54, bart wrote:
    On 17/09/2026 20:31, tTh wrote:
    On 9/17/26 17:46, bart wrote:

    Somebody needs some a few lines of info from a program, but the tool
    buries it in 1000 lines of output, and your suggestion is to just to
    scroll up and down trying to find it?

    Anything but fix the problem!

    ˙˙˙ May be you can code a patch who fix the^Wyour problem, and
    ˙˙˙ send it to the Gcc team ? Any positive contribution is
    ˙˙˙ benefit to all of us.

    I'm not interested in gcc. I have my own solutions.

    This is just one more annoying thing about that program. The issue
    here is that nobody is daring to criticise its crass behaviours, while
    trying to deflect issues onto users.

    Its crassness starts here:

    ˙˙ c:\c>gcc
    ˙˙ gcc: fatal error: no input files
    ˙˙ compilation terminated.


    Simple, clear, and to-the-point.

    Most command-line compilers give you version and help info when no
    parameters follow.

    Some do, some do not.

    Most command-line tools - gcc included - give you version information if
    you write "gcc --version", and help if you give "gcc --help".

    But at least it says something; try this:

    ˙˙ c:\c\as

    and it apparently hangs (it's waiting for you type an assembly program
    from the console!)

    Many programs can work as pipes.˙ It is waiting for input from stdin,
    not particularly from the console.˙ Programs that often get their input directly from other programs work this way.


    How did programs which work like some student's crude first console
    app ever make it into the wild?

    Perhaps it is because the developers know how to write programs designed
    to do useful jobs in a way that is convenient and efficient for the
    tasks they actually have to do?˙ Maybe the developers of "as" expected
    users to have a clue about what they are doing?


    Both are at odds with how similar command line tools work. gcc and as
    are even at odds with each other:

    - gcc complains about the missing input file (in a manner that treats it
    as a compilation error)

    - as defaults to reading content from stdin

    - Given two files, gcc compiles them independently; as assembles them
    after effectively combining them (imagine if gcc concatenated all the
    .c files you give it; it would be ludicrous).

    So I repeat that this is not how you would sensibly write such tools. I
    mean, is it unreasonable to expect '-shared' on Windows to result in a
    file ending with .dll rather than .exe?

    But gcc and as are given a pass because ... that's how the original
    crude versions worked and for some reason it was never practical to
    change it?

    In that case say so, rather than pretending that those quirks are really desirable features.

    I mean, you do 'gcc prog1.c', wait some time for it to produce 'a.exe'.
    Now you do 'gcc prog2.c', and it promptly overwrites the 'a.exe' from
    the last compile! That is quite laughable.

    At the moment, compiling my bignum library on Windows looks like this:

    gcc -shared -s bignum.c -o bignum.dll # .dll is 101KB

    bcc -dll bignum # .dll is 16KB


    Yes, I know, you never use gcc directly; invocations are hidden within makefiles, IDEs, and shell scripts.

    But I'm discussing their merits /as/ command-line tools that you use
    hands-on.




    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Michael S@3:633/10 to All on Fri Sep 18 17:45:09 2026
    On Thu, 17 Sep 2026 17:50:57 -0700
    Keith Thompson <Keith.S.Thompson+u@gmail.com> wrote:

    bart <bc@freeuk.com> writes:
    On 18/09/2026 01:04, Steven G. Kargl wrote:
    [...]
    Most people read (or at least skim) the documentation
    that comes with the software they use.

    Most people probably don't. They will try running such programs
    without input, as often that gives usage info.

    [...]

    You've seen how that approach fails.

    There are valid reasons for the way "as" behaves.

    Well, if you consider compatibility with weird notion of "user
    interface" of its original creator as a valid reason, then yes.
    Even I accept it as valid.
    Which does not make it less bad in the absolute sense.
    Desire to give to user an option to accept an input from standard
    input by itself is not unreasonable, bit it should be an option rather
    than default.

    Your assumptions
    about how you think it *should* behave have led you astray.
    I suggest that it is your approach, not "as", that needs to change.

    Quick summary: You are trying to use tools that were originally
    designed to be used in a Unix-like environment, and expecting them
    to behave like native Windows tools.


    as default is equelly bad design on both OSes.

    I'll explain further if you ask, but only if you convince me that
    you're actually interested in learning.




    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Michael S@3:633/10 to All on Fri Sep 18 17:53:17 2026
    On Fri, 18 Sep 2026 12:55:11 -0000 (UTC)
    cross@spitfire.i.gajendra.net (Dan Cross) wrote:

    In article <118i2mc$q9l1$1@dont-email.me>, bart <bc@freeuk.com>
    wrote:
    On 17/09/2026 23:06, Keith Thompson wrote:
    bart <bc@freeuk.com> writes:
    On 17/09/2026 08:24, tTh wrote:
    On 9/17/26 02:49, bart wrote:
    And I've no idea where gcc would look for its headers, other
    than where it keeps its system headers, or how to set it up to
    look permanently in certain places.
    ˙˙ You just have to read the fscking manual.
    https://gcc.gnu.org/onlinedocs/gcc/Environment-Variables.html

    Nobody uses environment variables any more.

    Obviously untrue.

    Let's say they're out of fashion.

    Why would you say such a thing? While they may not be the most
    elegant solution to a number of problems, they're very much in
    use, and "in fashion", at least on Unix-derived systems.

    - Dan C.


    Would you design a new program which behavior can be modified by
    environment variables? I don't mean standard environment variables, like
    locale (although that is also less than great) but environment
    variables specific to your program?


    --- 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 Fri Sep 18 17:24:16 2026
    On 18/09/2026 15:03, bart wrote:
    On 18/09/2026 12:11, David Brown wrote:
    On 17/09/2026 21:54, bart wrote:
    On 17/09/2026 20:31, tTh wrote:
    On 9/17/26 17:46, bart wrote:

    Somebody needs some a few lines of info from a program, but the
    tool buries it in 1000 lines of output, and your suggestion is to
    just to scroll up and down trying to find it?

    Anything but fix the problem!

    ˙˙˙ May be you can code a patch who fix the^Wyour problem, and
    ˙˙˙ send it to the Gcc team ? Any positive contribution is
    ˙˙˙ benefit to all of us.

    I'm not interested in gcc. I have my own solutions.

    This is just one more annoying thing about that program. The issue
    here is that nobody is daring to criticise its crass behaviours,
    while trying to deflect issues onto users.

    Its crassness starts here:

    ˙˙ c:\c>gcc
    ˙˙ gcc: fatal error: no input files
    ˙˙ compilation terminated.


    Simple, clear, and to-the-point.

    Most command-line compilers give you version and help info when no
    parameters follow.

    Some do, some do not.

    Most command-line tools - gcc included - give you version information
    if you write "gcc --version", and help if you give "gcc --help".

    But at least it says something; try this:

    ˙˙ c:\c\as

    and it apparently hangs (it's waiting for you type an assembly
    program from the console!)

    Many programs can work as pipes.˙ It is waiting for input from stdin,
    not particularly from the console.˙ Programs that often get their
    input directly from other programs work this way.


    How did programs which work like some student's crude first console
    app ever make it into the wild?

    Perhaps it is because the developers know how to write programs
    designed to do useful jobs in a way that is convenient and efficient
    for the tasks they actually have to do?˙ Maybe the developers of "as"
    expected users to have a clue about what they are doing?


    Both are at odds with how similar command line tools work. gcc and as
    are even at odds with each other:

    I am suspicious of your concept of "similar command line tools" here.
    gcc and as are not similar - they do very different jobs, and used in
    very different ways, and are written by completely independent groups.
    (The two groups cooperate and agree on standards, formats, flags, etc.,
    but write and maintain their projects in very different ways.)

    The program "gcc" is a driver program, written by the GCC folks, and run directly by developers. "as" is an assembler, written by the binutils
    folks, that is very rarely used directly by developers.

    "gcc" can be used with any assembler that follows expected standards - traditionally on *nix systems, the "system compiler" calls the "system assembler" and "system linker" to link with the "system library", all of
    which may be developed entirely independently. In a "typical" gcc installation, the assembler and linker are written by the same group,
    but the compiler and standard library are done by different people. But
    on a commercial Unix system, you might find more of the parts coming
    from the same commercial vendor.

    Within my projects, there are usually a couple of assembly files,
    generated by the various "project wizards" and "configuration generator"
    tools provided by microcontroller manufacturers - these cover things
    like very low-level startup code. There may also be an assembly file or
    two for task switching in an RTOS. (Most other assembly is inline
    assembly within C code.) I assemble these using gcc - I do not call
    "as" directly. Using the "gcc" driver program makes it a lot easier to
    keep consistent switches for choice of microcontroller details, paths,
    and all the other options I use. (Similarly, it is normal to use "gcc"
    for linking, rather than running "ld" directly.)

    So "gcc" and "as" are wildly different tools that are used in wildly
    different ways, written by completely separate groups of people. The
    fact that they have different defaults is hardly surprising - a compiler
    will rarely be used with piped input from outside, whereas for "as",
    that is by far the most common mode of operation.


    - gcc complains about the missing input file (in a manner that treats it
    ˙ as a compilation error)


    Yes. It /is/ a compilation error - there is nothing to compile (or
    assemble, or link).

    - as defaults to reading content from stdin

    Yes. That is far and away the most common usage of "as", to assemble
    the output generated by a compiler. It is indeed the primary task of
    "as" - being usable as a standalone assembler is a bonus feature.


    - Given two files, gcc compiles them independently; as assembles them
    ˙ after effectively combining them (imagine if gcc concatenated all the
    ˙ .c files you give it; it would be ludicrous).

    They are different kinds of programs, doing different things. Assembly
    files can reasonably be concatenated, C files cannot. "gcc" is a driver program, not a C compiler - it also deals with lots of different file
    types. It would not make sense to concatenate C files, assembly files,
    object files, linker command files, Fortran files, and whatever else you
    might choose to throw at it. (I did not know that "as" combines
    multiple assembly files as you describe. But it is not a driver program
    - it simply takes its input, and assembles it.)


    So I repeat that this is not how you would sensibly write such tools.

    "Truth by repetition" is not a valid argument. I appreciate that it is
    not how /you/ write assemblers and compilers, or how /you/ expect them
    to work. But we have already established that your opinions on such
    matters do not often match those of many others.

    I
    mean, is it unreasonable to expect '-shared' on Windows to result in a
    file ending with .dll rather than .exe?


    As I understand it, the format for dll and exe files is the same on
    Windows (as is the format for various other files), and both can contain directly executable code and resources that can be used by other
    programs. It's not something I have looked at in detail, however.

    Still, it is unreasonable to expect people to specify the name they want
    for a program or shared library? It is normal for a program (or shared library) to consist of multiple files - I think it would be highly
    unusual to want to turn a single "x.c" file into a dll "x.dll".

    But gcc and as are given a pass because ... that's how the original
    crude versions worked and for some reason it was never practical to
    change it?

    I don't use gcc to make dlls on Windows - or so files on Linux. And if
    I did, I would almost certainly not be doing so using a single source
    file. It would be part of a project (even if it was a relatively small project), and have a makefile to track the options I want. That would
    include the name of the output file.

    I am sure that it makes sense that "gcc -shared x.c" could generate
    "x.dll" on Windows. I am far from sure that failing to use "x.dll" as
    the default name is a bother to anyone else. Other than a quick test of
    how gcc works, it's hard to imagine a use-case.

    And of course, remember that gcc (and as) are native to an OS where the
    type of a file is determined by the file, not by part of its name.
    Naming conventions are definitely convenient, especially when it is hard
    to identify a file type accurately, but it is not the file extension
    that says if a file is an executable, or shared library, or whatever.


    In that case say so, rather than pretending that those quirks are really desirable features.

    I mean, you do 'gcc prog1.c', wait some time for it to produce 'a.exe'.
    Now you do 'gcc prog2.c', and it promptly overwrites the 'a.exe' from
    the last compile! That is quite laughable.


    So don't do that.

    Or, if it amuses you, laugh.


    At the moment, compiling my bignum library on Windows looks like this:

    ˙ gcc -shared -s bignum.c -o bignum.dll˙˙˙ # .dll is 101KB

    ˙ bcc -dll bignum˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙ # .dll is 16KB


    Yes, I know, you never use gcc directly; invocations are hidden within makefiles, IDEs, and shell scripts.

    But I'm discussing their merits /as/ command-line tools that you use hands-on.

    If you don't like the way gcc (or any other tools) work, and you feel
    that your own tools are better for your uses, then use your own tools.

    Or if you feel that you /have/ to use gcc, and that you can't cope with writing all these nasty, awkward switches and arguments, and think that
    build tools are just crutches for those that don't want to spend all day
    doing manual project management, then write a batch file:

    gcc-dll.bat :
    @echo off
    gcc -shared -s %1.c -o %1.dll


    gcc-exe.bat :
    @echo off
    gcc %1.c -o %1.exe


    There. After decades of gnashing your teeth and pulling out your hair,
    I've given you the solution. I can't imagine you will use it, but there
    it is.



    --- 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 Fri Sep 18 15:24:49 2026
    bart <bc@freeuk.com> writes:
    On 18/09/2026 01:04, Steven G. Kargl wrote:
    On Thu, 17 Sep 2026 20:54:35 +0100, bart wrote:

    Most command-line compilers give you version and help info when no
    parameters follow. But at least it says something; try this:

    c:\c\as

    and it apparently hangs (it's waiting for you type an assembly program
    from the console!)


    Most people read (or at least skim) the documentation
    that comes with the software they use.

    Most people probably don't. They will try running such programs without >input, as often that gives usage info.

    Please try to speak for yourself.

    Those familiar with unix would understand implicitly, as many
    commands will read from stdin if no filename is specified.



    'man' doesn't exist on Windows.

    So, use a web browser.

    https://man7.org/linux/man-pages/man1/as.1.html



    --- 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 Fri Sep 18 15:28:21 2026
    Michael S <already5chosen@yahoo.com> writes:
    On Thu, 17 Sep 2026 17:50:57 -0700
    Keith Thompson <Keith.S.Thompson+u@gmail.com> wrote:

    bart <bc@freeuk.com> writes:
    On 18/09/2026 01:04, Steven G. Kargl wrote:
    [...]
    Most people read (or at least skim) the documentation
    that comes with the software they use.

    Most people probably don't. They will try running such programs
    without input, as often that gives usage info.

    [...]

    You've seen how that approach fails.

    There are valid reasons for the way "as" behaves.

    Well, if you consider compatibility with weird notion of "user
    interface" of its original creator as a valid reason, then yes.
    Even I accept it as valid.
    Which does not make it less bad in the absolute sense.
    Desire to give to user an option to accept an input from standard
    input by itself is not unreasonable, bit it should be an option rather
    than default.

    That's your opinion. That's not the unix philosophy. Many
    unix commands default to stdin if no file name is specified
    (specifically to support streaming the output of one command
    to the input of another).

    By convention a single dash character may be specified
    in place of a filename to specify stdin.


    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Tim Rentsch@3:633/10 to All on Fri Sep 18 08:29:51 2026
    Kaz Kylheku <046-301-5902@kylheku.com> writes:

    On 2026-09-10, Chris M. Thomasson <chris.m.thomasson.1@gmail.com> wrote:

    On 9/9/2026 5:43 AM, David Brown wrote:
    [...]

    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.

    ________
    #ifndef __NUMBER_GENERATOR_H__
    #define __NUMBER_GENERATOR_H__ 1
    ________


    Is that __* non conformant? Does it breach the impl name prefix
    space?

    No matter what you name anything in C, you are playing roulette.
    Vendor extensions and new standard features introduce identifiers
    into namespaces that have not been hitherto reserved.

    It's like a traffic code. If you intrude into a namespace, it's
    like running a stop sign. Nothing bad might happen, but if it
    does, it is on you.

    However, C naming is like a residential neighborhood full of
    unguarded intersections, with only a few stop signs.

    There isn't anything reasonable you can do to 100% ensure you will
    never have a clash with anything in your C programming. (By
    "reasonable", I do not intend to introduce moving goalposts:
    specifically, I mean, not subjecting yourself to some horribly
    inconvenient naming scheme in every single namespace which makes
    it vanishingly improbable of ever seeing a clash).

    This picture is a lot more bleak than it needs to be. In practice
    dealing with possible naming conflicts is really not that hard.

    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From bart@3:633/10 to All on Fri Sep 18 16:31:33 2026
    On 18/09/2026 16:24, Scott Lurndal wrote:
    bart <bc@freeuk.com> writes:
    On 18/09/2026 01:04, Steven G. Kargl wrote:
    On Thu, 17 Sep 2026 20:54:35 +0100, bart wrote:

    Most command-line compilers give you version and help info when no
    parameters follow. But at least it says something; try this:

    c:\c\as

    and it apparently hangs (it's waiting for you type an assembly program >>>> from the console!)


    Most people read (or at least skim) the documentation
    that comes with the software they use.

    Most people probably don't. They will try running such programs without
    input, as often that gives usage info.

    Please try to speak for yourself.

    Those familiar with unix would understand implicitly, as many
    commands will read from stdin if no filename is specified.
    So how do they tell whether a program is hanging, or is waiting for input?

    FFS would it hurt to print a message showing what is expected?

    It is exasperating that people defend such poor UIs.



    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Michael S@3:633/10 to All on Fri Sep 18 18:34:09 2026
    On Fri, 18 Sep 2026 15:28:21 GMT
    scott@slp53.sl.home (Scott Lurndal) wrote:

    Michael S <already5chosen@yahoo.com> writes:
    On Thu, 17 Sep 2026 17:50:57 -0700
    Keith Thompson <Keith.S.Thompson+u@gmail.com> wrote:

    bart <bc@freeuk.com> writes:
    On 18/09/2026 01:04, Steven G. Kargl wrote:
    [...]
    Most people read (or at least skim) the documentation
    that comes with the software they use.

    Most people probably don't. They will try running such programs
    without input, as often that gives usage info.

    [...]

    You've seen how that approach fails.

    There are valid reasons for the way "as" behaves.

    Well, if you consider compatibility with weird notion of "user
    interface" of its original creator as a valid reason, then yes.
    Even I accept it as valid.
    Which does not make it less bad in the absolute sense.
    Desire to give to user an option to accept an input from standard
    input by itself is not unreasonable, bit it should be an option
    rather than default.

    That's your opinion. That's not the unix philosophy. Many
    unix commands default to stdin if no file name is specified
    (specifically to support streaming the output of one command
    to the input of another).

    There is big difference between utilities like grep or sort and
    something like as. Blindly treating them as the same is wrong.


    By convention a single dash character may be specified
    in place of a filename to specify stdin.


    The latter is reasonable. What as does is not.





    --- 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 Fri Sep 18 15:41:39 2026
    bart <bc@freeuk.com> writes:
    On 17/09/2026 23:06, Keith Thompson wrote:


    But if you have two versions A and B, and both their paths are listed in
    the PATH variable, then when B's gcc tries to run cc1.exe, it will be
    A's version, as A's path is listed first.

    It's the> responsibility of the gcc+FOO and gcc+BAR installers to arrange
    for their respecive gcc's to avoid conflicting with each other.
    Packaging gcc for Windows is more difficult than packaging gcc
    for Unix-like systems.

    It's not hard; it should really have used a path relative to B's gcc.exe.

    It would still pick A's gcc.exe if typing an unqualified 'gcc' by
    itself, but how does Linux solve this problem when you have two gcc's to >choose from?

    One can use modules:

    $ type gcc
    gcc is a tracked alias for /usr/bin/gcc
    $ gcc --version
    gcc (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0
    Copyright (C) 2017 Free Software Foundation, Inc.
    This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

    $ module use --append /nfs/Software/module/my-common/modulefiles
    $ module load gcc/11.3
    $ gcc --version
    gcc (GCC) 11.3.0
    Copyright (C) 2021 Free Software Foundation, Inc.
    This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

    $ type gcc
    gcc is a tracked alias for /nfs/asim/Software/bin/gcc-11.3.0/bin/gcc

    Generally when supporting multiple gcc releases, you'll also need
    multiple binutils releases (in case the compiler generates newer
    assembler instructions that aren't supported in older versions of
    as(1)).


    So, no comment on the fact that it can take three goes before gcc gets
    the DLL extension right?

    Keith has explained many times that the GNU Compiler development team
    develops for Unix, not Windows. Unix doesnt have DLLs (it does have
    shared objects, which IMO are superior to windows DLLs).

    --- 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 Fri Sep 18 15:44:11 2026
    David Brown <david.brown@hesbynett.no> writes:
    On 18/09/2026 03:04, bart wrote:
    On 17/09/2026 23:06, Keith Thompson wrote:
    bart <bc@freeuk.com> writes:
    On 17/09/2026 08:24, tTh wrote:
    On 9/17/26 02:49, bart wrote:
    And I've no idea where gcc would look for its headers, other than
    where it keeps its system headers, or how to set it up to look
    permanently in certain places.
    ˙ ˙˙ You just have to read the fscking manual.
    https://gcc.gnu.org/onlinedocs/gcc/Environment-Variables.html

    Nobody uses environment variables any more.

    Obviously untrue.

    Let's say they're out of fashion.

    Let's not. Lots of people use them for various purposes.

    Indeed, they're ubiquitous. Cf. $PATH, $HOME, $LANG (and $LC_*), $TERM
    are used extensively.


    --- 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 Fri Sep 18 15:47:01 2026
    Michael S <already5chosen@yahoo.com> writes:
    On Fri, 18 Sep 2026 12:55:11 -0000 (UTC)
    cross@spitfire.i.gajendra.net (Dan Cross) wrote:

    In article <118i2mc$q9l1$1@dont-email.me>, bart <bc@freeuk.com>
    wrote:
    On 17/09/2026 23:06, Keith Thompson wrote: =20
    bart <bc@freeuk.com> writes: =20
    On 17/09/2026 08:24, tTh wrote: =20
    On 9/17/26 02:49, bart wrote: =20
    And I've no idea where gcc would look for its headers, other
    than where it keeps its system headers, or how to set it up to
    look permanently in certain places. =20
    =C2=A0=C2=A0 You just have to read the fscking manual.
    https://gcc.gnu.org/onlinedocs/gcc/Environment-Variables.html =20

    Nobody uses environment variables any more. =20
    =20
    Obviously untrue. =20

    Let's say they're out of fashion. =20
    =20
    Why would you say such a thing? While they may not be the most
    elegant solution to a number of problems, they're very much in
    use, and "in fashion", at least on Unix-derived systems.
    =20
    - Dan C.
    =20

    Would you design a new program which behavior can be modified by
    environment variables? I don't mean standard environment variables, like >locale (although that is also less than great) but environment
    variables specific to your program?


    Absolutely.

    And they would be well documented in the manual page for the program.

    LD_DEBUG, for example, is quite useful in certain usage cases and
    effectively impossible to handle with a command line option flag.

    --- 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 Fri Sep 18 18:08:38 2026
    On 18/09/2026 17:34, Michael S wrote:
    On Fri, 18 Sep 2026 15:28:21 GMT
    scott@slp53.sl.home (Scott Lurndal) wrote:

    Michael S <already5chosen@yahoo.com> writes:
    On Thu, 17 Sep 2026 17:50:57 -0700
    Keith Thompson <Keith.S.Thompson+u@gmail.com> wrote:

    bart <bc@freeuk.com> writes:
    On 18/09/2026 01:04, Steven G. Kargl wrote:
    [...]
    Most people read (or at least skim) the documentation
    that comes with the software they use.

    Most people probably don't. They will try running such programs
    without input, as often that gives usage info.

    [...]

    You've seen how that approach fails.

    There are valid reasons for the way "as" behaves.

    Well, if you consider compatibility with weird notion of "user
    interface" of its original creator as a valid reason, then yes.
    Even I accept it as valid.
    Which does not make it less bad in the absolute sense.
    Desire to give to user an option to accept an input from standard
    input by itself is not unreasonable, bit it should be an option
    rather than default.

    That's your opinion. That's not the unix philosophy. Many
    unix commands default to stdin if no file name is specified
    (specifically to support streaming the output of one command
    to the input of another).

    There is big difference between utilities like grep or sort and
    something like as. Blindly treating them as the same is wrong.


    By convention a single dash character may be specified
    in place of a filename to specify stdin.


    The latter is reasonable. What as does is not.


    From the manual page of "as" :

    """
    as is primarily intended to assemble the output of the GNU C compiler
    "gcc" for use by the linker "ld". Nevertheless, we've tried to make as assemble correctly everything that other assemblers for the same machine
    would assemble. Any exceptions are documented explicitly. This doesn't
    mean as always uses the same syntax as another assembler for the same architecture; for example, we know of several incompatible versions of
    680x0 assembly language syntax.

    Each time you run as it assembles exactly one source program. The
    source program is made up of one or more files. (The standard input is
    also a file.)

    You give as a command line that has zero or more input file names. The
    input files are read (from left file name to right). A command-line
    argument (in any position) that has no special meaning is taken to be an
    input file name.

    If you give as no file names it attempts to read one input file from the
    as standard input, which is normally your terminal. You may have to
    type ctl-D to tell as there is no more program to assemble.

    Use -- if you need to explicitly name the standard input file in your
    command line.
    """

    The primary use of "as" is for assembling the output of "gcc". I think
    it would have been fine if "as" had required one or two dashes, or
    another option, to indicated using stdin as the input - but I don't see
    it as unreasonable that by default it works according to the stated
    primary use of the program.

    A common way to handle assembly files on Linux is to use "gcc file.s",
    with whatever additional options you want, not "as file.s", just as it
    is common to use "gcc" for linking rather than running "ld" directly.


    Were I writing a new assembler for Linux, I would probably not make it
    work as a pipe by default - and require a dash or two, or another
    command-line option. Running "my-new-assembler" with no options or
    files would exit immediately, perhaps with a "no input files" error or
    perhaps with a "use --help for help" message. (Or perhaps with no
    output at all, which I think would also be a reasonable choice.) So
    while I think "act as a pipe" is a reasonable choice for "as" with no
    input files, I think there are other choices that are at least somewhat better.

    However, where is any of this actually likely to cause an issue in the
    real world? No one would expect "as" to do anything useful without any
    input, or an option like "--version" or "--help". The only people
    likely to be confused are those who have no idea what the program is,
    and try to figure it out by typing "as". The flaw, IMHO, is not that
    "as" works as a pipe by default, but its name is too short and generic.
    "gas" or "gasm" would have been better.


    On the other hand, I have a number of times run a "grep" command and
    wondered why it was taking so long - because I'd forgotten to give it
    the files to search! (That's my fault, not grep's.)





    --- 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 Fri Sep 18 11:06:13 2026
    David Brown <david.brown@hesbynett.no> writes:
    [...]
    On 17/09/2026 21:54, bart wrote:
    [...]
    I'm not interested in gcc. [...]
    [...]
    The program "gcc" is a driver program, written by the GCC folks, and
    run directly by developers. "as" is an assembler, written by the
    binutils folks, that is very rarely used directly by developers.

    David, bart say he's not interested in gcc. I suggest taking him
    at his word.

    [...]

    --
    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 Keith Thompson@3:633/10 to All on Fri Sep 18 11:26:24 2026
    David Brown <david.brown@hesbynett.no> writes:
    [...]
    Were I writing a new assembler for Linux, I would probably not make it
    work as a pipe by default - and require a dash or two, or another command-line option. Running "my-new-assembler" with no options or
    files would exit immediately, perhaps with a "no input files" error or perhaps with a "use --help for help" message. (Or perhaps with no
    output at all, which I think would also be a reasonable choice.) So
    while I think "act as a pipe" is a reasonable choice for "as" with no
    input files, I think there are other choices that are at least
    somewhat better.

    If your new assembler were intended to be a drop-in replacement for
    "as", are certain that this behavior would not break existing tools?
    How sure are you that gcc, or clang, or some other tool, doesn't send
    input to the assembler in a pipe? And why shouldn't they do so?

    [...]

    --
    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 Keith Thompson@3:633/10 to All on Fri Sep 18 11:29:15 2026
    bart <bc@freeuk.com> writes:
    On 18/09/2026 16:24, Scott Lurndal wrote:
    [...]
    Those familiar with unix would understand implicitly, as many
    commands will read from stdin if no filename is specified.
    So how do they tell whether a program is hanging, or is waiting for input?

    By typing Control-D.

    FFS would it hurt to print a message showing what is expected?

    Yes, it would. I won't offer an explanation because you would not care
    about it or admit that you understand it.

    It is exasperating that people defend such poor UIs.

    It is exasperating *to you* that people try to *explain* UIs that you
    dislike.

    --
    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 Keith Thompson@3:633/10 to All on Fri Sep 18 11:34:59 2026
    scott@slp53.sl.home (Scott Lurndal) writes:
    bart <bc@freeuk.com> writes:
    On 17/09/2026 23:06, Keith Thompson wrote:
    But if you have two versions A and B, and both their paths are listed in >>the PATH variable, then when B's gcc tries to run cc1.exe, it will be
    A's version, as A's path is listed first.

    It's the> responsibility of the gcc+FOO and gcc+BAR installers to arrange >>> for their respecive gcc's to avoid conflicting with each other.
    Packaging gcc for Windows is more difficult than packaging gcc
    for Unix-like systems.

    It's not hard; it should really have used a path relative to B's gcc.exe.

    It would still pick A's gcc.exe if typing an unqualified 'gcc' by
    itself, but how does Linux solve this problem when you have two gcc's to >>choose from?

    One can use modules:
    [...]
    $ module use --append /nfs/Software/module/my-common/modulefiles
    $ module load gcc/11.3
    [...]

    On Ubuntu, the "module" command isn't installed by default. You can
    install it via the "environment-modules" package. (I've used it
    on SGI and Cray systems, where it originated, but not on Ubuntu,
    and not in the last couple of decades or so.)

    [...]

    --
    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 bart@3:633/10 to All on Fri Sep 18 20:07:42 2026
    On 18/09/2026 16:24, David Brown wrote:
    On 18/09/2026 15:03, bart wrote:

    So "gcc" and "as" are wildly different tools that are used in wildly
    different ways, written by completely separate groups of people.˙ The
    fact that they have different defaults is hardly surprising - a compiler will rarely be used with piped input from outside, whereas for "as",
    that is by far the most common mode of operation.

    Actually, gcc on Windows seems to generate temporary .s files that are submitted to 'as'. Piping isn't used.

    Both gcc and 'as' take inputs which are one or more files (sequences of
    bytes) and write outputs that are one or more files.

    You probably can't get any simpler than that in a computer program.

    Neither of them are really intended for interactive use either: that is, interaction while they run, beyond invoking them.

    But if either seriously expect source code to be entered 'live', then
    they should show a prompt; how hard would that be?

    (An older version of 'bcc' supported this:

    c:\bcx>bcc -stdin t
    Reading from stdin. Finish with Ctrl-Z:
    #include <stdio.h>
    int main(void) {puts("Hey it worked!");}
    ^Z

    c:\bcx>t
    Hey it worked!
    It still needs a filename, which is used for the output. And notice the prompt. See, it's easy.)

    - Given two files, gcc compiles them independently; as assembles them
    ˙˙ after effectively combining them (imagine if gcc concatenated all the
    ˙˙ .c files you give it; it would be ludicrous).

    They are different kinds of programs, doing different things.˙ Assembly files can reasonably be concatenated, C files cannot.

    That is nonsense. ASM can contain local, non-exported symbols just like
    HLLs. For example two people might be writing two ASM files and they
    shouldn't need to ensure that their choices of labels do not clash.

    Neither should they /depend/ on using a symbol that may be provided by
    another file without needing to formally export it from one file.

    With as, you can take any ASM file, split in arbitrarily into two halves
    A.s and B.s, and be able to assemble using:

    as A.s B.s

    Yes, that works because it concatenates them together again. But what is
    the point of that? Each half will be incomplete; this will likely fail:

    gcc -c A.s B.s

    because each is assumed to be well-formed.

    So the question is, what sort of crazy person maintains ASM programs as
    a collection of malformed files that can only be assembled via 'as' when presented in an exact order?

    You are defending something that is ludicrous.


    "gcc" is a driver
    program, not a C compiler - it also deals with lots of different file
    types.

    So what's the name of the actual C compiler then, cc1.exe? That doesn't
    appear usable by itself:

    cc1 Hangs
    cc1 hello.c Errors (can't find include files)
    cc1 --help Lists 2118 options


    ˙ (I did not know that "as" combines
    multiple assembly files as you describe.˙ But it is not a driver program
    - it simply takes its input, and assembles it.)

    So what's the name of the assembler proper? It seems everything comes
    under the 'gcc' umbrella, out of necessity rather than convenience,
    since the different components - cc1, as, ld - are pretty much unusable
    by themselves.

    In this case, gcc must be the de facto C compiler, but since it does
    every other job too, it makes it harder to use.

    Here's an example of more dedicated tools (which I thought was the Unix
    ethos) working together better.

    'cc' is the development version of bcc. It can be made to discrete intermediate representations before it gets to EXE. That works like this:

    c:\cx>cc -p hello # generate IL
    Compiling hello.c to hello.pcl

    c:\cx>pc -a hello # convert IL to ASM
    Processing hello.pcl to hello.asm

    c:\cx>aa hello # assemble ASM to EXE
    Assembling hello.asm to hello.exe

    c:\cx>hello
    Hello, World!

    Notice:

    * Each tool consistently works the same way

    * Each tool knows the type of input file it deals with so
    the file extension is optional (none are typed here)

    * Each tool can somehow figure out the name of the output file
    (I really scratched my head over that one)

    * Not needing the extension also simplifies scripting:

    cc -p %1 && pc -a %1 && aa %1 && %1

    It's not about leaving them out here, but if the parameter to this batch
    file was "hello.c" rather than "hello", it would screw things up. It is
    a bonus though.

    to work.˙ But we have already established that your opinions on such
    matters do not often match those of many others.

    OK. For some irrational reason, you are defending some behaviours
    determined decades ago, which were clearly wrong, ludicrous, unsafe, or inconsistent.

    You know, it would cost you nothing to say, Bart, you're right. But for historical and other reasons we're stuck with them and need to make the
    best of a bad job.

    I mean, is it unreasonable to expect '-shared' on Windows to result in
    a file ending with .dll rather than .exe?


    As I understand it, the format for dll and exe files is the same on
    Windows (as is the format for various other files), and both can contain directly executable code and resources that can be used by other
    programs.

    They have the same format, but files used as DLLs have extra stuff:

    * Base relocation tables
    * Must have relocatable code
    * I think there is an extra segment
    * An export table
    * Different flags are set in the header

    The .dll extension is normally used for these. Experiments trying to
    load a DLL via LoadLibrary (ie. dlopen on Linux) suggest that an
    extension other than .dll would be troublesome.

    LoadLibrary Arg lib.dll lib.exe (actual name of DLL)

    "lib" Yes No
    "lib.dll" Yes No
    "lib.exe" No Yes

    So it makes sense to use "lib" or "lib.dll" as the argument, and for
    DLLs to use ".dll".

    In any case, using .exe for DLLs would be confusing.

    Still, it is unreasonable to expect people to specify the name they want
    for a program or shared library?

    I was mildly surprised that gcc on Windows allows "-o prog" and gcc will generate the file "prog.exe" without needing the extension.

    This could reasonably lead people to think that with "-shared", it would
    write a .dll file. They would be wrong.

    ˙ It is normal for a program (or shared
    library) to consist of multiple files - I think it would be highly
    unusual to want to turn a single "x.c" file into a dll "x.dll".

    C compilers that don't follow gcc (clang follows gcc, and tcc follows it
    on Linux only), tend to take the name of the first submitted C file as
    the default name of the output, when there is one output.

    (-c -S options generate multiple files.)

    I am sure that it makes sense that "gcc -shared x.c" could generate
    "x.dll" on Windows.˙ I am far from sure that failing to use "x.dll" as
    the default name is a bother to anyone else.˙ Other than a quick test of
    how gcc works, it's hard to imagine a use-case.

    It's just wrong. A million people will use gcc and some of those will encounter some issue like this which at best wastes their time.

    And of course, remember that gcc (and as) are native to an OS where the
    type of a file is determined by the file, not by part of its name.

    Fine. In that case don't bother with the extension if the extension is a
    lie.

    But for DLLs, the extensions is important to make it visible, and there
    will of course be further checks that are done.


    I mean, you do 'gcc prog1.c', wait some time for it to produce
    'a.exe'. Now you do 'gcc prog2.c', and it promptly overwrites the
    'a.exe' from the last compile! That is quite laughable.


    So don't do that.

    Something else which is just plain wrong, and can waste a lot of time.
    When you have to do twice the work of specifying an input, or you may
    have to repeat a lengthy compile if you need to run an earlier, now overwritten, a.exe again.

    If you don't like the way gcc (or any other tools) work, and you feel
    that your own tools are better for your uses, then use your own tools.

    That's exactly what I do. But gcc came up in this thread.
    Or if you feel that you /have/ to use gcc, and that you can't cope with writing all these nasty, awkward switches and arguments, and think that build tools are just crutches for those that don't want to spend all day doing manual project management, then write a batch file:

    gcc-dll.bat :
    @echo off
    gcc -shared -s %1.c -o %1.dll


    gcc-exe.bat :
    @echo off
    gcc %1.c -o %1.exe


    There.

    I do that too. It is a small C program called gc used like this:

    gc prog
    gc prog opt

    It generates prog.exe and also adds the long-winded options needed for
    my generated C code.

    But it's not flexible enough for ad hoc needs. Then I have to use gcc
    and it's a nuisance because of its quirks.

    After decades of gnashing your teeth and pulling out your hair,
    I've given you the solution.˙ I can't imagine you will use it, but there
    it is.

    It's a workaround. gcc is what, 85,000 source files, but I still have to
    write scripts to make it usable?!





    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From bart@3:633/10 to All on Fri Sep 18 20:14:29 2026
    On 18/09/2026 19:29, Keith Thompson wrote:
    bart <bc@freeuk.com> writes:
    On 18/09/2026 16:24, Scott Lurndal wrote:
    [...]
    Those familiar with unix would understand implicitly, as many
    commands will read from stdin if no filename is specified.
    So how do they tell whether a program is hanging, or is waiting for input?

    By typing Control-D.

    How would they know without a message?

    But suppose they did that, what happens, the program stops? What if it
    was just busy; wouldn't Ctrl-D screw it up?


    FFS would it hurt to print a message showing what is expected?

    Yes, it would. I won't offer an explanation because you would not care
    about it or admit that you understand it.

    Try me.

    (In my last post I showed an example of my C compiler taking input from
    stdin (requested, not as default!) and it displays a message. The world
    is still turning.



    --- 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 Fri Sep 18 12:26:38 2026
    bart <bc@freeuk.com> writes:
    [...]
    But if either seriously expect source code to be entered 'live', then
    they should show a prompt; how hard would that be?

    There is no serious expectation that "as" will be read its input
    from a keyboard. You are complaining about things you clearly do
    not understand and do not want to understand.

    --
    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 Keith Thompson@3:633/10 to All on Fri Sep 18 12:42:50 2026
    bart <bc@freeuk.com> writes:
    On 18/09/2026 19:29, Keith Thompson wrote:
    bart <bc@freeuk.com> writes:
    On 18/09/2026 16:24, Scott Lurndal wrote:
    [...]
    Those familiar with unix would understand implicitly, as many
    commands will read from stdin if no filename is specified.
    So how do they tell whether a program is hanging, or is waiting for input? >> By typing Control-D.

    How would they know without a message?

    By understanding how Unix commands typically work, and that typing
    Ctrl-D is the normal way to trigger and end-of-file condition when
    reading from a keyboard.

    But suppose they did that, what happens, the program stops? What if it
    was just busy; wouldn't Ctrl-D screw it up?

    No.

    FFS would it hurt to print a message showing what is expected?
    Yes, it would. I won't offer an explanation because you would not
    care about it or admit that you understand it.

    Try me.

    Let's be clear. Are you asking me to explain? If I explain, will you
    accept my explanation as a sincere attempt to educate you, and not whine
    to me about the fact that "as" doesn't behave the way you think it
    should?

    Are you really interested in learning something? Your history here does
    not suggest that, but if you've changed your mind about that, I'm
    willing to try to explain it. (Though I'm not sure I can explain
    anything that hasn't already been explained in this thread.)

    (In my last post I showed an example of my C compiler taking input
    from stdin (requested, not as default!) and it displays a message. The
    world is still turning.

    Some programs read input from stdin if they don't receive any file name arguments. Others do not. Both approaches are valid. Apparently your
    C compiler is an example of the latter.

    One particular program, "as", can read its input from stdin. Have you
    somehow inferred from that that we all think your compiler should do the
    same?

    --
    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 Tim Rentsch@3:633/10 to All on Fri Sep 18 12:58:16 2026
    Janis Papanagnou <janis_papanagnou+ng@hotmail.com> writes:

    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.

    The module ideas in Modula came from the earlier programming
    language Mesa, which was developed at Xerox PARC.

    To give credit where it is due, it is almost certainly true that
    some of the constructs in Mesa were influenced by or inspired by
    features in Pascal. But modules began in Mesa (and perhaps also
    some earlier work done by Butler Lampson but I haven't read that
    material).

    Mesa was developed in roughly the same time frame as early C.
    There was a Mesa compiler for one architecture, with Mesa code
    running on that architecture, in 1974. Later that same year
    work was started on a Mesa compiler for another architecture,
    running I believe early the next year. As it turns out I was
    writing code in Mesa a few years before I started writing code
    in C. It's nice to have modules as first class constructs in
    the language; in practice though I find the C pattern of .h/.c
    relationships to be workable, in place of modules, for the
    software development needs of typical software projects.

    --- 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 Fri Sep 18 20:28:20 2026
    Michael S <already5chosen@yahoo.com> writes:
    On Fri, 18 Sep 2026 15:28:21 GMT
    scott@slp53.sl.home (Scott Lurndal) wrote:

    Michael S <already5chosen@yahoo.com> writes:
    On Thu, 17 Sep 2026 17:50:57 -0700
    Keith Thompson <Keith.S.Thompson+u@gmail.com> wrote:

    bart <bc@freeuk.com> writes:
    On 18/09/2026 01:04, Steven G. Kargl wrote:
    [...]
    Most people read (or at least skim) the documentation
    that comes with the software they use.

    Most people probably don't. They will try running such programs
    without input, as often that gives usage info.

    [...]

    You've seen how that approach fails.

    There are valid reasons for the way "as" behaves.

    Well, if you consider compatibility with weird notion of "user
    interface" of its original creator as a valid reason, then yes.
    Even I accept it as valid.
    Which does not make it less bad in the absolute sense.
    Desire to give to user an option to accept an input from standard
    input by itself is not unreasonable, bit it should be an option
    rather than default.

    That's your opinion. That's not the unix philosophy. Many
    unix commands default to stdin if no file name is specified
    (specifically to support streaming the output of one command
    to the input of another).

    There is big difference between utilities like grep or sort and
    something like as. Blindly treating them as the same is wrong.

    Historically speaking, as(1) was part of the c compiler pipeline
    accepting the output of the

    cpp file.c | c0 | c1 | c2 | as > file.o


    From v6 C c20.c:

    if (argc>1) {
    if ((fin = open(argv[1], 0)) < 0) {
    printf("C2: can't find %s\n", argv[1]);
    exit(1);
    }
    } else
    fin = dup(0);
    if (argc>2) {
    if ((fout = creat(argv[2], 0666)) < 0) {
    fout = 1;
    printf("C2: can't create %s\n", argv[2]);
    exit(1);
    }
    } else
    fout = dup(1);

    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Kenny McCormack@3:633/10 to All on Fri Sep 18 20:39:04 2026
    In article <118jvog$1grii$2@kst.eternal-september.org>,
    Keith Thompson <Keith.S.Thompson+u@gmail.com> wrote:
    David Brown <david.brown@hesbynett.no> writes:
    [...]
    Were I writing a new assembler for Linux, I would probably not make it
    work as a pipe by default - and require a dash or two, or another
    command-line option. Running "my-new-assembler" with no options or
    files would exit immediately, perhaps with a "no input files" error or
    perhaps with a "use --help for help" message. (Or perhaps with no
    output at all, which I think would also be a reasonable choice.) So
    while I think "act as a pipe" is a reasonable choice for "as" with no
    input files, I think there are other choices that are at least
    somewhat better.

    If your new assembler were intended to be a drop-in replacement for
    "as", are certain that this behavior would not break existing tools?
    How sure are you that gcc, or clang, or some other tool, doesn't send
    input to the assembler in a pipe? And why shouldn't they do so?

    It is generally an error condition if both of the following are true:

    1) A program (*) is reading from standard input by default - i.e.,
    without the user having explicitly requested it (via a command line arg
    like "-" or "/dev/stdin").

    2) stdin is a tty.

    I have gotten in the habit of having my programs check for both of the
    above conditions being true (the later using the POSIX "isatty()" function)
    and error-aborting if they are. Note that this allows normal operation if stdin is a pipe or a redirected file (or anything else other than a tty).

    Also, another way that I've seen some programs deal with this - that I
    think might make Bart happy - is to detect the condition (that stdin is a
    tty) and issue a prompt in that case (rather than just aborting).

    (*) Meaning, a program that takes command line args, which specify input
    files, such as a compiler, or an assembler or something like AWK or Perl.

    --
    Ted Cruz sounds like every straight man's first wife.

    Ted Cruz is such a closet case his first name should have been Tom.

    Show some respect! Someday, Ted will have a promising career selling reverse mortgages.

    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From bart@3:633/10 to All on Fri Sep 18 22:57:27 2026
    On 18/09/2026 20:26, Keith Thompson wrote:
    bart <bc@freeuk.com> writes:
    [...]
    But if either seriously expect source code to be entered 'live', then
    they should show a prompt; how hard would that be?

    There is no serious expectation that "as" will be read its input
    from a keyboard.

    Not intentionally perhaps. But it will happen every time a newcomer to
    it, or someone who has mercifully forgotten the last time they used it,
    runs 'as' with no inputs.

    You are complaining about things you clearly do
    not understand and do not want to understand.

    WTH is there to understand about it?

    'as' (even the choice of name is terrible as it needs quotes to
    distinguish it from the word) just works poorly. Maybe that was by
    design at the time, but apparently such things are impossible to fix so
    it has to work that way for eternity.

    (Of course, creating 'as2' would be out of the question.)


    Is 'as' even intended to be used in an interactive console session? I
    don't mean typing in code to stdin, but invoking it as a program via
    live typing.

    It sounds like many here do not do that; it is only invoked from scripts
    or via other tools.

    If that is the case, then they are in no position to criticise my
    comments about it.



    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Steven G. Kargl@3:633/10 to All on Sat Sep 19 00:19:06 2026
    On Fri, 18 Sep 2026 20:14:29 +0100, bart wrote:

    On 18/09/2026 19:29, Keith Thompson wrote:
    bart <bc@freeuk.com> writes:
    On 18/09/2026 16:24, Scott Lurndal wrote:
    [...]
    Those familiar with unix would understand implicitly, as many
    commands will read from stdin if no filename is specified.
    So how do they tell whether a program is hanging, or is waiting for input? >>
    By typing Control-D.

    How would they know without a message?

    <Rinse>

    By reading the friendly documentation that comes with the tool.

    <repeat>

    --
    steve

    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From bart@3:633/10 to All on Sat Sep 19 02:06:09 2026
    On 19/09/2026 01:19, Steven G. Kargl wrote:
    On Fri, 18 Sep 2026 20:14:29 +0100, bart wrote:

    On 18/09/2026 19:29, Keith Thompson wrote:
    bart <bc@freeuk.com> writes:
    On 18/09/2026 16:24, Scott Lurndal wrote:
    [...]
    Those familiar with unix would understand implicitly, as many
    commands will read from stdin if no filename is specified.
    So how do they tell whether a program is hanging, or is waiting for input? >>>
    By typing Control-D.

    How would they know without a message?

    <Rinse>

    By reading the friendly documentation that comes with the tool.
    In the case of 'as', that is 2,500 lines of text.

    For gcc, it is 26,000 lines.

    Look, just admit these ancient applications have a shitty interface that
    no one has been able to improve or hasn't been allowed to.

    Why pretend that how they work is actually desirable?

    I've just installed Go-lang. If I type 'go', it doesn't say FATAL ERROR,
    it says this:

    c:\go\bin>go
    Go is a tool for managing Go source code.
    Usage:
    go <command> [arguments]
    The commands are:
    ...

    It looks easy on the eye too. It is worth making the effort.

    Further, if I compile hello.go with it ('go build hello.go') it creates
    an output file called 'hello.exe'. How TF did it manage to figure that out?

    Because gcc can't do that at all; it generates 'a.exe' and 26K lines of
    help isn't going to explain why that is better.

    It's funny how all these idiosyncratic programs always seem to originate
    from Unix.

    --- 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 Fri Sep 18 20:20:55 2026
    bart <bc@freeuk.com> writes:
    [...]
    Look, just admit these ancient applications have a shitty interface
    that no one has been able to improve or hasn't been allowed to.

    Why pretend that how they work is actually desirable?
    [...]

    I apologize to the group for engaging in this discussion.

    The "as" command is not about the C programming language.
    Explanations about how to use it might be marginally topical, since
    it's commonly invoked (implicitly!) by C compilation systems, but
    opinions about whether its interface is reasonable or shitty are not.
    I expect bart will continue to whine about it. I will no longer
    help him to do so.

    I had offered to try to explain it to him. I hereby rescind
    that offer.

    If he wanted to discuss it reasonably, there are other newsgroups
    where he might do so.

    --
    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 Steven G. Kargl@3:633/10 to All on Sat Sep 19 03:26:44 2026
    On Sat, 19 Sep 2026 02:06:09 +0100, bart wrote:

    On 19/09/2026 01:19, Steven G. Kargl wrote:
    On Fri, 18 Sep 2026 20:14:29 +0100, bart wrote:

    On 18/09/2026 19:29, Keith Thompson wrote:
    bart <bc@freeuk.com> writes:
    On 18/09/2026 16:24, Scott Lurndal wrote:
    [...]
    Those familiar with unix would understand implicitly, as many
    commands will read from stdin if no filename is specified.
    So how do they tell whether a program is hanging, or is waiting for input?

    By typing Control-D.

    How would they know without a message?

    <Rinse>

    By reading the friendly documentation that comes with the tool.
    In the case of 'as', that is 2,500 lines of text.


    The info is in the 5th paragraph of the Description section.
    This is the 20 and 21st lines of material that you has a user
    should have at least skimmed. The first two sections are
    simply an abbreviated enumeration of options and supported
    targets.

    Again, why would you use a tool without actually learn how
    the tool works?

    --
    steve

    --- 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 Sat Sep 19 09:03:35 2026
    On 2026-09-18 11:37, David Brown wrote:
    On 18/09/2026 09:10, Janis Papanagnou wrote:
    On 2026-09-15 12:53, David Brown wrote:
    On 15/09/2026 11:51, Janis Papanagnou wrote:
    [...]

    And we all know we should be writing "if (a == 5)", with decent
    spacing :-)

    Sure. Above was just a deliberate terse form for inline reference.
    Usually I'm using probably more spacing inline and between lines
    and chapters than the average programmer would find tolerable. ;-)

    I like space - it aids legibility.˙ There's a reason the biggest key on
    the keyboard is the spacebar, and the second biggest is the return key.

    And the third biggest the Backspace key to quickly erase all this
    ugly code we wrote? ;-)


    Yes, things have gotten much better since the dates back then when
    I did my professional programming in C/C++.


    Tools have certainly got better, but the default warnings in compilers progress much too slowly IMHO.˙ (Of course I can enable all the warning flags I like for my own use - but I'd prefer if everyone else used them more!)

    Well, I cannot really tell about the more recent behaviors. All I
    noticed was that I've got (or could enable) more diagnostics than
    in earlier days, and that the information got better (in content
    and in display representation) - it would certainly be bad if it
    were otherwise.


    You might be astonished but I don't recall to have needed any explicit
    warnings setting; our policy was a zero-warning approach (by the default
    warnings of our compilers), and where we identified any needs beyond we
    communicated with the build-management to make it the company default.
    Having good programmers, providing trainings and courses, helped also.


    If the default warnings for your compiler matched something like "-Wall"
    in gcc, then that could be a good starting point.

    I don't recall what the settings were. (As said, I rarely needed to
    make individual settings.)

    I don't know what compiler(s) you used,

    I seem to recall that (in the late 1980's) on SunOS we used gcc/g++
    (for some reason I don't recall any more). Later we usually used
    compilers that came with the commercial systems (on AIX for example
    xlC, IIRC). Privately I used only the GNU tools (but back then in my professional days I did only very few private projects).

    but for many IME the default warnings are pretty
    feeble.˙ But it can certainly be impractical to insist on a specific
    list of different warning options, especially when a project includes third-party code that might have different 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 Sat Sep 19 09:16:48 2026
    On 2026-09-18 17:44, Scott Lurndal wrote:
    David Brown <david.brown@hesbynett.no> writes:
    On 18/09/2026 03:04, bart wrote:
    On 17/09/2026 23:06, Keith Thompson wrote:
    bart <bc@freeuk.com> writes:
    On 17/09/2026 08:24, tTh wrote:
    On 9/17/26 02:49, bart wrote:
    And I've no idea where gcc would look for its headers, other than >>>>>>> where it keeps its system headers, or how to set it up to look
    permanently in certain places.
    ˙ ˙˙ You just have to read the fscking manual.
    https://gcc.gnu.org/onlinedocs/gcc/Environment-Variables.html

    Nobody uses environment variables any more.

    Obviously untrue.

    Let's say they're out of fashion.

    Let's not. Lots of people use them for various purposes.

    Indeed, they're ubiquitous. Cf. $PATH, $HOME, $LANG (and $LC_*), $TERM
    are used extensively.

    Yes, these are the typical "standard" ones we use and ever used on
    Unix (and maybe also elsewhere).

    But I think the poster may have other environment variables in mind;
    those that programmers invent and users (system configurators) set.

    It had been indeed not uncommon - I wouldn't call that "in vogue",
    though - that environment variables were used to pass arguments to
    a system. This way of parameterizing is IME very error prone, since
    you "control" software in an obscure way. (That's why our standards
    deprecated use of environment variables, or rather, allowed just a
    single one per (sub-)project (as an entry point to the software
    configuration). The software configuration was generally all done
    by transparent and comprehensible parameter files.)

    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 Sat Sep 19 09:38:22 2026
    On 2026-09-18 18:08, David Brown wrote:
    On 18/09/2026 17:34, Michael S wrote:
    On Fri, 18 Sep 2026 15:28:21 GMT
    scott@slp53.sl.home (Scott Lurndal) wrote:
    [...]

    By convention a single dash character may be specified
    in place of a filename to specify stdin.

    The latter is reasonable. What as does is not.

    From the manual page of "as" :
    [snip]

    The primary use of "as" is for assembling the output of "gcc".˙ I think
    it would have been fine if "as" had required one or two dashes, or
    another option, to indicated using stdin as the input - but I don't see
    it as unreasonable that by default it works according to the stated
    primary use of the program.

    A common way to handle assembly files on Linux is to use "gcc file.s",
    with whatever additional options you want, not "as file.s", just as it
    is common to use "gcc" for linking rather than running "ld" directly.

    Were I writing a new assembler for Linux, I would probably not make it
    work as a pipe by default - and require a dash or two, or another command-line option.˙ Running "my-new-assembler" with no options or
    files would exit immediately, perhaps with a "no input files" error or perhaps with a "use --help for help" message.˙ (Or perhaps with no
    output at all, which I think would also be a reasonable choice.)˙ So
    while I think "act as a pipe" is a reasonable choice for "as" with no
    input files, I think there are other choices that are at least somewhat better.

    However, where is any of this actually likely to cause an issue in the
    real world?˙ No one would expect "as" to do anything useful without any input, or an option like "--version" or "--help".˙ The only people
    likely to be confused are those who have no idea what the program is,
    and try to figure it out by typing "as".˙ The flaw, IMHO, is not that
    "as" works as a pipe by default, but its name is too short and generic. "gas" or "gasm" would have been better.

    I agree with all you wrote. - The problem on Unixes is more that
    there's not exactly a single method used on that interface level
    that one can rely on. One has to read the diagnostics and/or the
    man page. And if there's someone coming from another "IT world"
    he might have issues. (Most folks will learn the concepts while
    others will complain, and sometimes not stop complaining, instead
    of just informing themselves about the concepts and concrete use).

    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 Sat Sep 19 09:45:46 2026
    On 2026-09-18 17:24, Scott Lurndal wrote:
    bart <bc@freeuk.com> writes:
    On 18/09/2026 01:04, Steven G. Kargl wrote:
    On Thu, 17 Sep 2026 20:54:35 +0100, bart wrote:

    Most command-line compilers give you version and help info when no
    parameters follow. But at least it says something; try this:

    c:\c\as

    and it apparently hangs (it's waiting for you type an assembly program >>>> from the console!)


    Most people read (or at least skim) the documentation
    that comes with the software they use.

    Most people probably don't. They will try running such programs without
    input, as often that gives usage info.

    Please try to speak for yourself.

    Those familiar with unix would understand implicitly, as many
    commands will read from stdin if no filename is specified.

    I think the problem has indeed to do which ones "IT-socialization";
    IIRC the piping-concept was originally unknown in the "DOS world",
    and when they at some point introduced the '|' (pipe) syntax their
    "OS" created a temporary file anyway. (Please CMIIW.)

    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 Sat Sep 19 09:56:42 2026
    On 2026-09-19 05:26, Steven G. Kargl wrote:
    On Sat, 19 Sep 2026 02:06:09 +0100, bart wrote:
    [...]

    Again, why would you use a tool without actually learn how
    the tool works?

    Inherent (and incurable) mental inabilities?

    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 Sat Sep 19 10:45:52 2026
    On 19/09/2026 04:26, Steven G. Kargl wrote:
    On Sat, 19 Sep 2026 02:06:09 +0100, bart wrote:

    By reading the friendly documentation that comes with the tool.
    In the case of 'as', that is 2,500 lines of text.


    The info is in the 5th paragraph of the Description section.
    This is the 20 and 21st lines of material that you has a user
    should have at least skimmed. The first two sections are
    simply an abbreviated enumeration of options and supported
    targets.

    Again, why would you use a tool without actually learn how
    the tool works?

    Last year someone asked for my C compiler to generate GAS format. So
    learning how that worked was the main obstacle, since docs for it are so
    poor.

    Of course, I had to be able to test the output by assembling it, and
    only 'as' could do that. (Since my 'client' wanted to assemble the
    output with their own version of 'as', and the results processed with
    their linker, I tested directly against 'as' rather than use gcc.)

    It quirks were a nuisance but for this one-off task I used a script
    ass.bat like this:

    as %1.asm -o%1.obj && gcc %1.obj -o%1.exe

    it was invoked as:

    ass prog

    This then did the same job as my own assembler that already worked
    exactly like that:

    aa prog

    So it's not a question of me having to learn all this stuff, I can
    figure it out in a few minutes.

    I'm questioning why such a tool, called an 'assembler', worked in such a strange manner in the first place:

    * /Silently/ defaults to reading from the keyboard if you type its
    name

    * Writes its output file to 'a.out' and not 'prog.o' or 'prog.obj'

    * If assembling two or more assembly files, it silently combines
    them into one

    And:

    * Why NOBODY here (bar Michael S!) questions that and seems to think
    it is completely reasonable when it is clearly at odds with how
    other assemblers generally work

    Apparently a tool like this can get away with anything provide its
    behaviour matches it docs! Example:

    > man as
    - skip 1234 lines -
    "Note: Running as with no input will immediately delete all your
    files"
    ....

    That's alright then; if that happens, it would be my fault! Definitely
    not a poor UI.

    (In fact something like this DOES happen; if I have a critical file - on Windows - that happens to be called 'a.out', then 'as' will silently
    overwrite it, if I type 'as file.s' expecting it to write 'file.o'.)









    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From bart@3:633/10 to All on Sat Sep 19 11:08:40 2026
    On 19/09/2026 08:56, Janis Papanagnou wrote:
    On 2026-09-19 05:26, Steven G. Kargl wrote:
    On Sat, 19 Sep 2026 02:06:09 +0100, bart wrote:
    [...]

    Again, why would you use a tool without actually learn how
    the tool works?

    Inherent (and incurable) mental inabilities?
    Regarding assemblers, usually that is the very least of the problems
    when using an unfamiliar one for the first time.

    The simplest thing to do is just try it and see what see what happens.
    And the most obvious thing to try is to type its name:


    c:\fasm>fasm
    flat assembler version 1.73.35
    usage: fasm <source> [output]
    ...

    c:\fasm>yasm
    yasm: No input files specified

    c:\fasm>aa
    AA7 Assembler 29-Aug-2026
    Usage:
    aa filename[.asm] # Assemble filename.asm to filename.exe
    ...

    c:\fasm>nasm
    nasm: fatal: no input file specified
    Type nasm -h for help.

    c:\fasm>as
    <hangs>
    ^C

    Here, fasm and aa show usage info. Nasm invites you to use '-h' for help.

    Yasm is not too helpful. Still, you can infer that you need to supply
    the name of your file!

    The least helpful, if you use this approach, is 'as'.

    So it is perfectly reasonable for somebody to question why it sucks like
    that.

    But according to you, anyone trying out programs like this without first seeking and then perusing 1000s of lines of content, is mentally deficient?

    I might consider anyone who routinely did that to be to have a condition.

    In any case, it's quite possible to invoke some of these inadvertently
    by mistyping. Oh, I forgot, you are a perfect typist too!


    --- 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 Sat Sep 19 13:01:55 2026
    On 19/09/2026 09:03, Janis Papanagnou wrote:
    On 2026-09-18 11:37, David Brown wrote:
    On 18/09/2026 09:10, Janis Papanagnou wrote:
    On 2026-09-15 12:53, David Brown wrote:
    On 15/09/2026 11:51, Janis Papanagnou wrote:
    [...]

    And we all know we should be writing "if (a == 5)", with decent
    spacing :-)

    Sure. Above was just a deliberate terse form for inline reference.
    Usually I'm using probably more spacing inline and between lines
    and chapters than the average programmer would find tolerable. ;-)

    I like space - it aids legibility.˙ There's a reason the biggest key
    on the keyboard is the spacebar, and the second biggest is the return
    key.

    And the third biggest the Backspace key to quickly erase all this
    ugly code we wrote? ;-)


    :-)


    Yes, things have gotten much better since the dates back then when
    I did my professional programming in C/C++.


    Tools have certainly got better, but the default warnings in compilers
    progress much too slowly IMHO.˙ (Of course I can enable all the
    warning flags I like for my own use - but I'd prefer if everyone else
    used them more!)

    Well, I cannot really tell about the more recent behaviors. All I
    noticed was that I've got (or could enable) more diagnostics than
    in earlier days, and that the information got better (in content
    and in display representation) - it would certainly be bad if it
    were otherwise.


    Absolutely - warnings of all sorts have got better over time in gcc.
    But I would like to see more of them enabled by default, so that common mistakes are unavoidably identified. (Though I understand why the gcc developers are conservative here.)


    --- 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 Sat Sep 19 13:10:02 2026
    On 18/09/2026 20:26, Keith Thompson wrote:
    David Brown <david.brown@hesbynett.no> writes:
    [...]
    Were I writing a new assembler for Linux, I would probably not make it
    work as a pipe by default - and require a dash or two, or another
    command-line option. Running "my-new-assembler" with no options or
    files would exit immediately, perhaps with a "no input files" error or
    perhaps with a "use --help for help" message. (Or perhaps with no
    output at all, which I think would also be a reasonable choice.) So
    while I think "act as a pipe" is a reasonable choice for "as" with no
    input files, I think there are other choices that are at least
    somewhat better.

    If your new assembler were intended to be a drop-in replacement for
    "as", are certain that this behavior would not break existing tools?

    No. I had not said my hypothetical new assembler would be a drop-in replacement for "as" - if it were, then obviously I'd follow the
    behaviour of "as" here. It is unlikely that there is much to be gained
    in replacing "as" directly - it does all that is needed for a companion
    to a compiler. The only point, I would say, of writing a new assembler
    for Linux would be for additional features or capabilities. (Or it
    could be done for fun!)

    How sure are you that gcc, or clang, or some other tool, doesn't send
    input to the assembler in a pipe? And why shouldn't they do so?


    gcc certainly sends its output to as using a pipe if you specify the
    "-pipe" option. Otherwise, it uses temporary files (on Linux, this is
    pretty much the same efficiency as the temporary files are normally
    never actually saved to the filesystem. Maybe Bart could tell us if
    giving gcc the "-pipe" option affects the speed on his Windows gcc
    toolchain).


    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From tTh@3:633/10 to All on Sat Sep 19 13:25:43 2026
    On 9/19/26 12:08, bart wrote:

    In any case, it's quite possible to invoke some of these inadvertently
    by mistyping. Oh, I forgot, you are a perfect typist too!

    $ sl


    --
    ** **
    * tTh des Bourtoulots *
    * http://maison.tth.netlib.re/ *
    ** **

    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From bart@3:633/10 to All on Sat Sep 19 13:20:43 2026
    On 19/09/2026 12:10, David Brown wrote:
    On 18/09/2026 20:26, Keith Thompson wrote:
    David Brown <david.brown@hesbynett.no> writes:
    [...]
    Were I writing a new assembler for Linux, I would probably not make it
    work as a pipe by default - and require a dash or two, or another
    command-line option.˙ Running "my-new-assembler" with no options or
    files would exit immediately, perhaps with a "no input files" error or
    perhaps with a "use --help for help" message.˙ (Or perhaps with no
    output at all, which I think would also be a reasonable choice.)˙ So
    while I think "act as a pipe" is a reasonable choice for "as" with no
    input files, I think there are other choices that are at least
    somewhat better.

    If your new assembler were intended to be a drop-in replacement for
    "as", are certain that this behavior would not break existing tools?

    No.˙ I had not said my hypothetical new assembler would be a drop-in replacement for "as" - if it were, then obviously I'd follow the
    behaviour of "as" here.˙ It is unlikely that there is much to be gained
    in replacing "as" directly - it does all that is needed for a companion
    to a compiler.˙ The only point, I would say, of writing a new assembler
    for Linux would be for additional features or capabilities.˙ (Or it
    could be done for fun!)

    How sure are you that gcc, or clang, or some other tool, doesn't send
    input to the assembler in a pipe?˙ And why shouldn't they do so?


    gcc certainly sends its output to as using a pipe if you specify the "- pipe" option.˙ Otherwise, it uses temporary files (on Linux, this is
    pretty much the same efficiency as the temporary files are normally
    never actually saved to the filesystem.˙ Maybe Bart could tell us if
    giving gcc the "-pipe" option affects the speed on his Windows gcc toolchain).


    For building sql.c, then using -pipe consistently gave compile-times of
    around 7.25 seconds vs 7.5 or so without it. About 4% faster, but this
    at -O0.

    Using -O3, then it was 50.1 seconds vs 52.5 seconds (tested once only).
    I expected the difference to be still around 0.25 seconds (the EXE sizes
    won't be that different), but then I also forgot to do -s.

    It needs a better set of tests really. But in general it seems to be insignificant, given that gcc is slow anyway, and even less significant
    with optimisations on.

    The same program is built by bcc in 0.23 seconds, direct to EXE.

    Using a discrete ASM step, then it's 0.53 seconds in all; generating 8MB
    of ASM is the bottleneck (4.1 seconds from .c to .asm; 0.12 seconds to assemble 270Kloc.)

    In my original C compiler, it /had/ to go through assembly. But the
    assembler was built-in, and the intermediate ASM files were kept in
    memory. This streamlined the process, but ASM still had to be generated.

    That version compiles this in 0.38 seconds, via that internal ASM. There
    is a option to turn off that internal ASM, but that seemed to make no difference. Then I looked closer and it was perhaps 0.005 seconds
    (timings vary by that much anyway), assuming the switch worked.


    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Jim Jackson@3:633/10 to All on Sat Sep 19 13:39:42 2026
    On 2026-09-18, Keith Thompson <Keith.S.Thompson+u@gmail.com> wrote:

    Are you really interested in learning something? Your history here does
    not suggest that, but if you've changed your mind about that, I'm
    willing to try to explain it. (Though I'm not sure I can explain
    anything that hasn't already been explained in this thread.)

    (In my last post I showed an example of my C compiler taking input
    from stdin (requested, not as default!) and it displays a message. The
    world is still turning.

    Some programs read input from stdin if they don't receive any file name arguments. Others do not. Both approaches are valid. Apparently your
    C compiler is an example of the latter.

    One particular program, "as", can read its input from stdin. Have you somehow inferred from that that we all think your compiler should do the same?


    Some fish have spent their lives living in a very small pool and know it
    very well, and then they go for a trip in the sea and it is very
    frightening! It contains environments and objects that they have no comprehension off, and if the fish is old and set in his or her ways
    the wider world will always be a mystery!

    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Jim Jackson@3:633/10 to All on Sat Sep 19 13:46:09 2026
    On 2026-09-18, fir <profesor.fir@gmail.com> wrote:

    in most cases i think it may be understood but sometimes if i read my
    post some words i dont understand

    this is becouse of unfortunate typos, but i write a big amounts of
    posts and if iwould carefully read it all before osting i couldnt focus

    (so its eventually better to write is as a stream of thought and then
    post errata to it)

    Do you also program in this way? Sometimes it is worth taking time to
    think before writing.

    I mostly ignore your scribblings precisely because of your stream of consciousness style. I suspect a lot of others do too. But keep on if
    you are happy!

    --- 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 Sat Sep 19 15:09:09 2026
    bart <bc@freeuk.com> writes:
    On 19/09/2026 01:19, Steven G. Kargl wrote:
    On Fri, 18 Sep 2026 20:14:29 +0100, bart wrote:

    <snip> a bunch of irrelevent text that boils down to a single acronym:

    RTFM

    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From bart@3:633/10 to All on Sat Sep 19 16:17:52 2026
    On 19/09/2026 16:09, Scott Lurndal wrote:
    bart <bc@freeuk.com> writes:
    On 19/09/2026 01:19, Steven G. Kargl wrote:
    On Fri, 18 Sep 2026 20:14:29 +0100, bart wrote:

    <snip> a bunch of irrelevent text that boils down to a single acronym:

    RTFM

    So nothing ever changes or improves. Nobody asks questions, nothing is
    ever criticised, and the same quirks perpetuate forever to keep
    compatibilty.



    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From bart@3:633/10 to All on Sat Sep 19 16:24:58 2026
    On 19/09/2026 14:39, Jim Jackson wrote:
    On 2026-09-18, Keith Thompson <Keith.S.Thompson+u@gmail.com> wrote:

    Are you really interested in learning something? Your history here does
    not suggest that, but if you've changed your mind about that, I'm
    willing to try to explain it. (Though I'm not sure I can explain
    anything that hasn't already been explained in this thread.)

    (In my last post I showed an example of my C compiler taking input
    from stdin (requested, not as default!) and it displays a message. The
    world is still turning.

    Some programs read input from stdin if they don't receive any file name
    arguments. Others do not. Both approaches are valid. Apparently your
    C compiler is an example of the latter.

    One particular program, "as", can read its input from stdin. Have you
    somehow inferred from that that we all think your compiler should do the
    same?


    Some fish have spent their lives living in a very small pool and know it
    very well, and then they go for a trip in the sea and it is very
    frightening! It contains environments and objects that they have no comprehension off, and if the fish is old and set in his or her ways
    the wider world will always be a mystery!

    So the 'as' assembler and its cronies are the wider world?!

    Or are these prehistoric utilities the fish? So the habit of naming
    every output file 'a.out' will persist for ever?



    --- 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 Sat Sep 19 17:27:25 2026
    On 18/09/2026 21:07, bart wrote:
    On 18/09/2026 16:24, David Brown wrote:
    On 18/09/2026 15:03, bart wrote:

    ˙So "gcc" and "as" are wildly different tools that are used in wildly
    different ways, written by completely separate groups of people.˙ The
    fact that they have different defaults is hardly surprising - a
    compiler will rarely be used with piped input from outside, whereas
    for "as", that is by far the most common mode of operation.

    Actually, gcc on Windows seems to generate temporary .s files that are submitted to 'as'. Piping isn't used.

    Piping is an option that is used on some systems, and not on others, and
    it can be enabled with "gcc -pipe". Whether you are using a pipe or a temporary file, the prime use of "as" is not as a program run by a user,
    but as a program run by "gcc".


    Both gcc and 'as' take inputs which are one or more files (sequences of bytes) and write outputs that are one or more files.

    You probably can't get any simpler than that in a computer program.


    So now gcc is a simple program?

    Neither of them are really intended for interactive use either: that is, interaction while they run, beyond invoking them.

    True.


    But if either seriously expect source code to be entered 'live', then
    they should show a prompt; how hard would that be?

    That's a meaningless question, as the pre-condition is clearly false.

    I accept that it is fine for a program to print a quick help message
    when run with incomplete or incorrect arguments. But it is also fine
    for it to give an error message. And for some programs, it can be
    appropriate to show nothing when given no arguments, or to wait for
    input from stdin. All options are reasonable for some kinds of
    programs. In some programs you wrote, you picked one method, in some
    programs other people have written, they picked a different solution.
    Your personal opinions do not form the requirements for all the world's software.

    - Given two files, gcc compiles them independently; as assembles them
    ˙˙ after effectively combining them (imagine if gcc concatenated all the >>> ˙˙ .c files you give it; it would be ludicrous).

    They are different kinds of programs, doing different things.
    Assembly files can reasonably be concatenated, C files cannot.

    That is nonsense. ASM can contain local, non-exported symbols just like HLLs. For example two people might be writing two ASM files and they shouldn't need to ensure that their choices of labels do not clash.


    Sometimes assembly files can be concatenated - it depends on how they
    are written. People often use local symbols and labels (numerical
    labels, or .L labels). But at other times, you are entirely correct
    that there may be clashes if you concatenate two random assembly files.

    So let me be more nuanced - /sometimes/ it is reasonable to concatenate assembly files, and assembly files may be written with that in mind. It
    is almost never reasonable to concatenate C source files.

    For an assembler designed with direct use as a primary aim, you could reasonably pick a different handling of multiple source files - maybe
    they would be assembled independently to generate multiple object files,
    or maybe they would be rejected as invalid use of the assembler (with a
    nice, friendly help message if you don't like error messages). For an assembler designed primarily to be called from a compiler driver
    program, it doesn't much matter as the compiler takes the responsibility
    of getting the command line arguments right, or of making sure that if
    it sends multiple source files, they can and should be concatenated.


    "gcc" is a driver program, not a C compiler - it also deals with lots
    of different file types.

    So what's the name of the actual C compiler then, cc1.exe? That doesn't appear usable by itself:

    No, it is probably not of much use by itself - it is intended solely to
    be run from gcc (or g++, or other gcc frontend driver programs).


    So what's the name of the assembler proper? It seems everything comes
    under the 'gcc' umbrella, out of necessity rather than convenience,
    since the different components - cc1, as, ld - are pretty much unusable
    by themselves.

    "as" is the name of the assembler "proper". It is not part of gcc, and
    nor is "ld". ("ld" and "as" are both part of the "binutils" project.)
    And no one else has suggested that "as" is not usable by itself - merely
    that this is not the /primary/ use-case. This is different for "cc1",
    which is absolutely intended only as an internal program called from
    "gcc", and there is not likely to be any reason to run it directly.

    Note that failing to print a help message when you run "as" without
    parameters does not make it "pretty much unusable".

    Also note that in the *nix world, the behaviour of gcc, cc1, as, ld and
    other related programs here are quite normal. They follow conventions
    used by other toolchains found in the *nix world, and people can and do
    mix and match to a certain extent. I think that's less common now that
    the *nix world has pretty much settled on Linux and BSD, with the
    commercial unix systems and their dedicated toolchains no longer as popular.


    to work.˙ But we have already established that your opinions on such
    matters do not often match those of many others.

    OK. For some irrational reason, you are defending some behaviours
    determined decades ago, which were clearly wrong, ludicrous, unsafe, or inconsistent.


    Many people here have put quite a bit of time and effort into explaining things to you - why things are the way they are, what advantages they
    have, what disadvantages they have. We also explain how to use the
    tools the way they are, and why your various complaints are generally
    not actually problems in practice.

    None of us here wrote any of the tools under discussion. Thus we are
    not "defending" anything. We are /explaining/. We might also offer
    opinions about whether we like something or not, or find it useful -
    those are subjective opinions.

    You know, it would cost you nothing to say, Bart, you're right. But for historical and other reasons we're stuck with them and need to make the
    best of a bad job.

    When I agree with you, I am happy to say so. You would know that if you
    ever read what others wrote.


    I mean, is it unreasonable to expect '-shared' on Windows to result
    in a file ending with .dll rather than .exe?


    As I understand it, the format for dll and exe files is the same on
    Windows (as is the format for various other files), and both can
    contain directly executable code and resources that can be used by
    other programs.

    They have the same format, but files used as DLLs have extra stuff:

    ˙ * Base relocation tables
    ˙ * Must have relocatable code
    ˙ * I think there is an extra segment
    ˙ * An export table
    ˙ * Different flags are set in the header

    The .dll extension is normally used for these. Experiments trying to
    load a DLL via LoadLibrary (ie. dlopen on Linux) suggest that an
    extension other than .dll would be troublesome.

    LoadLibrary Arg˙˙˙˙ lib.dll˙˙˙˙˙ lib.exe (actual name of DLL)

    "lib"˙˙˙˙˙˙˙˙˙˙˙˙˙˙˙ Yes˙˙˙˙˙˙˙˙ No
    "lib.dll"˙˙˙˙˙˙˙˙˙˙˙ Yes˙˙˙˙˙˙˙˙ No
    "lib.exe"˙˙˙˙˙˙˙˙˙˙˙ No˙˙˙˙˙˙˙˙˙ Yes

    So it makes sense to use "lib" or "lib.dll" as the argument, and for
    DLLs to use ".dll".

    In any case, using .exe for DLLs would be confusing.

    Having different file extensions can be very helpful, particularly on
    Windows where they are integral to the system. (I find it infuriating
    that the Windows gui hides file extensions by default - it's the first
    thing I turn off when I have to use a Windows machine.)

    There are reasonable uses of files as both executables and libraries.
    Very often in my Python coding, I will have a Python file that is
    intended for use as a "library" (i.e., to be imported from other
    modules, scripts or Python shells) but which can also be run directly
    for test purposes or as simple command-line programs. For large enough programs, it is normal to separate the dll's from the exe's, but
    combining them in one file would surely suit your preference for minimum number of files.


    Still, it is unreasonable to expect people to specify the name they
    want for a program or shared library?

    I was mildly surprised that gcc on Windows allows "-o prog" and gcc will generate the file "prog.exe" without needing the extension.


    This may be a configurable option for building gcc. It may also be a
    feature of "ld", or whatever linker is used in your Winlibs installation.

    This could reasonably lead people to think that with "-shared", it would write a .dll file. They would be wrong.

    So they have to learn how to use their tools. In the days before
    google, that might have been inconvenient. First, of course, they
    should learn that they are not using "gcc on Windows" - they are using
    the "Winlibs" toolchain, or whatever.


    ˙ It is normal for a program (or shared library) to consist of
    multiple files - I think it would be highly unusual to want to turn a
    single "x.c" file into a dll "x.dll".

    C compilers that don't follow gcc (clang follows gcc, and tcc follows it
    on Linux only), tend to take the name of the first submitted C file as
    the default name of the output, when there is one output.


    That seems reasonable for compilation - compiling "file.c" to "file.o".
    gcc does that - "gcc -c file.c" produces "file.o". (It does not bother
    me one way or the other - in real use, I always give gcc a specific
    output file because I don't mix my generated object files and my source
    code in the same directories.)

    Generating an exe file, or a shared library, is very likely to involve
    more than one file. Naming the output after one file is therefore not helpful. Naming it "a.out" is not particularly helpful either, but
    that's the tradition.

    (-c -S options generate multiple files.)

    I am sure that it makes sense that "gcc -shared x.c" could generate
    "x.dll" on Windows.˙ I am far from sure that failing to use "x.dll" as
    the default name is a bother to anyone else.˙ Other than a quick test
    of how gcc works, it's hard to imagine a use-case.

    It's just wrong. A million people will use gcc and some of those will encounter some issue like this which at best wastes their time.


    None of this has even crossed my mind until you brought it up. I'm sure
    you are right that it will waste some time for some people, and I don't disagree that sometimes the default behaviour could have been better -
    but I simply cannot see it as being a matter worth fussing about.

    (In posts where you have pointed out that gcc, without additional
    arguments, accepts code that your compiler has treated as an error, I
    have often agreed - or at least said a warning would be better than
    silent acceptance.)

    And of course, remember that gcc (and as) are native to an OS where
    the type of a file is determined by the file, not by part of its name.

    Fine. In that case don't bother with the extension if the extension is a lie.

    But for DLLs, the extensions is important to make it visible, and there
    will of course be further checks that are done.


    I don't disagree that it makes sense for a program generating a dll on
    Windows to give the result a .dll extension by default (though that
    extension is not necessarily correct - .oxc, .cpl, .drv, .fon, .icl are apparently all dll files). I just disagree that it matters very much,
    or that it is going to cause anyone confusion, mistakes, or wasted time.
    It would, at most, only be relevant to people writing the command line
    by hand for each build - and they are already wasting their own time by
    not using at least some kind of build automation or script (or at least
    a simple bat file!).


    I mean, you do 'gcc prog1.c', wait some time for it to produce
    'a.exe'. Now you do 'gcc prog2.c', and it promptly overwrites the
    'a.exe' from the last compile! That is quite laughable.


    So don't do that.

    Something else which is just plain wrong, and can waste a lot of time.
    When you have to do twice the work of specifying an input, or you may
    have to repeat a lengthy compile if you need to run an earlier, now overwritten, a.exe again.


    Again, when you see this as an issue, it is because you are doing things wrong.

    Remember, you are not doing software development here, or doing any programming. You are not writing code and producing executables or
    libraries. People who do that use the best tools they can get to make
    their job easier and give better results - they use proper editors or
    ides, and proper build tools. No sane developer wants to type in a
    compile command line for every compilation, with all the flags and
    options that suit their own particular needs (which vary enormously from developer to developer) - they have it typed in already in a makefile or
    a batch file, or generated with cmake, or whatever floats their boat.
    One little extra argument to give the required output filename is an irrelevant detail.

    Now, I realise that the way I use my tools and the setups I have is not necessarily typical of anyone else. But a quick check of the command
    line used for each individual compile in my current project shows 111 arguments ( over about 2300 characters. That includes all the include directory flags (blame idiot microcontroller manufacturer SDKs for their necessity, not me or gcc), a couple of dozen specifically chosen
    optimisation flags, a dozen flags for details of the exact target
    processor features, lots and lots of warning flags, and one argument specifying the output file name and directory. For the linking call to
    gcc - the one you are most upset about - there are about 760 arguments
    over 60,000 characters due to the 729 object file names and their
    directories. (These are all automatically generated by my makefiles.)
    That's a /real/ project for a /real/ program. Do you honestly think
    that having a better (IYHO) default choice of output filename would make
    a difference?

    All you are doing is faffing around with meaningless tests on the command-line. It bears no relationship to actual software development.

    If you don't like the way gcc (or any other tools) work, and you feel
    that your own tools are better for your uses, then use your own tools.

    That's exactly what I do. But gcc came up in this thread.
    Or if you feel that you /have/ to use gcc, and that you can't cope
    with writing all these nasty, awkward switches and arguments, and
    think that build tools are just crutches for those that don't want to
    spend all day doing manual project management, then write a batch file:

    gcc-dll.bat :
    @echo off
    gcc -shared -s %1.c -o %1.dll


    gcc-exe.bat :
    @echo off
    gcc %1.c -o %1.exe


    There.

    I do that too. It is a small C program called gc used like this:

    ˙ gc prog
    ˙ gc prog opt

    It generates prog.exe and also adds the long-winded options needed for
    my generated C code.

    So if even /you/ - renowned failure at build automation and sceptic to anything that might make your life easier - don't actually have any
    problems from gcc's choices of default, then why are you fussing about
    it? Do you imagine there are C programmers out there who are less
    competent than you at making batch files or using other appropriate tools?


    But it's not flexible enough for ad hoc needs. Then I have to use gcc
    and it's a nuisance because of its quirks.

    After decades of gnashing your teeth and pulling out your hair, I've
    given you the solution.˙ I can't imagine you will use it, but there it
    is.

    It's a workaround. gcc is what, 85,000 source files, but I still have to write scripts to make it usable?!


    My car is built from 85,000 pieces - it still needs a driver to make it usable.


    --- 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 Sat Sep 19 17:30:39 2026
    On 19/09/2026 14:20, bart wrote:
    On 19/09/2026 12:10, David Brown wrote:
    On 18/09/2026 20:26, Keith Thompson wrote:
    David Brown <david.brown@hesbynett.no> writes:
    [...]
    Were I writing a new assembler for Linux, I would probably not make it >>>> work as a pipe by default - and require a dash or two, or another
    command-line option.˙ Running "my-new-assembler" with no options or
    files would exit immediately, perhaps with a "no input files" error or >>>> perhaps with a "use --help for help" message.˙ (Or perhaps with no
    output at all, which I think would also be a reasonable choice.)˙ So
    while I think "act as a pipe" is a reasonable choice for "as" with no
    input files, I think there are other choices that are at least
    somewhat better.

    If your new assembler were intended to be a drop-in replacement for
    "as", are certain that this behavior would not break existing tools?

    No.˙ I had not said my hypothetical new assembler would be a drop-in
    replacement for "as" - if it were, then obviously I'd follow the
    behaviour of "as" here.˙ It is unlikely that there is much to be
    gained in replacing "as" directly - it does all that is needed for a
    companion to a compiler.˙ The only point, I would say, of writing a
    new assembler for Linux would be for additional features or
    capabilities.˙ (Or it could be done for fun!)

    How sure are you that gcc, or clang, or some other tool, doesn't send
    input to the assembler in a pipe?˙ And why shouldn't they do so?


    gcc certainly sends its output to as using a pipe if you specify the
    "- pipe" option.˙ Otherwise, it uses temporary files (on Linux, this
    is pretty much the same efficiency as the temporary files are normally
    never actually saved to the filesystem.˙ Maybe Bart could tell us if
    giving gcc the "-pipe" option affects the speed on his Windows gcc
    toolchain).


    For building sql.c, then using -pipe consistently gave compile-times of around 7.25 seconds vs 7.5 or so without it. About 4% faster, but this
    at -O0.

    Using -O3, then it was 50.1 seconds vs 52.5 seconds (tested once only).
    I expected the difference to be still around 0.25 seconds (the EXE sizes won't be that different), but then I also forgot to do -s.


    Okay, thanks. There's no need for any more tests - it's enough to see
    that it makes a small but in practice negligible difference.


    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Michael S@3:633/10 to All on Sat Sep 19 21:00:12 2026
    On Fri, 18 Sep 2026 18:08:38 +0200
    David Brown <david.brown@hesbynett.no> wrote:

    On 18/09/2026 17:34, Michael S wrote:
    On Fri, 18 Sep 2026 15:28:21 GMT
    scott@slp53.sl.home (Scott Lurndal) wrote:

    Michael S <already5chosen@yahoo.com> writes:
    On Thu, 17 Sep 2026 17:50:57 -0700
    Keith Thompson <Keith.S.Thompson+u@gmail.com> wrote:

    bart <bc@freeuk.com> writes:
    On 18/09/2026 01:04, Steven G. Kargl wrote:
    [...]
    Most people read (or at least skim) the documentation
    that comes with the software they use.

    Most people probably don't. They will try running such programs
    without input, as often that gives usage info.

    [...]

    You've seen how that approach fails.

    There are valid reasons for the way "as" behaves.

    Well, if you consider compatibility with weird notion of "user
    interface" of its original creator as a valid reason, then yes.
    Even I accept it as valid.
    Which does not make it less bad in the absolute sense.
    Desire to give to user an option to accept an input from standard
    input by itself is not unreasonable, bit it should be an option
    rather than default.

    That's your opinion. That's not the unix philosophy. Many
    unix commands default to stdin if no file name is specified
    (specifically to support streaming the output of one command
    to the input of another).

    There is big difference between utilities like grep or sort and
    something like as. Blindly treating them as the same is wrong.


    By convention a single dash character may be specified
    in place of a filename to specify stdin.


    The latter is reasonable. What as does is not.


    From the manual page of "as" :

    """
    as is primarily intended to assemble the output of the GNU C compiler
    "gcc" for use by the linker "ld". Nevertheless, we've tried to make
    as assemble correctly everything that other assemblers for the same
    machine would assemble. Any exceptions are documented explicitly.
    This doesn't mean as always uses the same syntax as another assembler
    for the same architecture; for example, we know of several
    incompatible versions of 680x0 assembly language syntax.


    I don't know when this paragraph was written.
    Today's gnu as is pretty reasonable tool for assembler develpment.
    Decent macro capabilities etc... Likely, not on par with
    macro-assemblers of IBM mainframes or of VAX/VMS, but rather similar in capabilities to Microsoft's Masm or with nasm.
    Certainly it is far more complete tool than what would be neeaded to
    process gcc output into objects.


    Each time you run as it assembles exactly one source program. The
    source program is made up of one or more files. (The standard input
    is also a file.)

    You give as a command line that has zero or more input file names.
    The input files are read (from left file name to right). A
    command-line argument (in any position) that has no special meaning
    is taken to be an input file name.

    If you give as no file names it attempts to read one input file from
    the as standard input, which is normally your terminal. You may have
    to type ctl-D to tell as there is no more program to assemble.

    Use -- if you need to explicitly name the standard input file in your command line.
    """

    The primary use of "as" is for assembling the output of "gcc". I
    think it would have been fine if "as" had required one or two dashes,
    or another option, to indicated using stdin as the input - but I
    don't see it as unreasonable that by default it works according to
    the stated primary use of the program.

    A common way to handle assembly files on Linux is to use "gcc
    file.s", with whatever additional options you want, not "as file.s",
    just as it is common to use "gcc" for linking rather than running
    "ld" directly.


    Were I writing a new assembler for Linux, I would probably not make
    it work as a pipe by default - and require a dash or two, or another command-line option. Running "my-new-assembler" with no options or
    files would exit immediately, perhaps with a "no input files" error
    or perhaps with a "use --help for help" message. (Or perhaps with no
    output at all, which I think would also be a reasonable choice.) So
    while I think "act as a pipe" is a reasonable choice for "as" with no
    input files, I think there are other choices that are at least
    somewhat better.

    However, where is any of this actually likely to cause an issue in
    the real world? No one would expect "as" to do anything useful
    without any input, or an option like "--version" or "--help". The
    only people likely to be confused are those who have no idea what the
    program is, and try to figure it out by typing "as".

    Those people are commnon.

    The flaw, IMHO,
    is not that "as" works as a pipe by default, but its name is too
    short and generic. "gas" or "gasm" would have been better.


    On the other hand, I have a number of times run a "grep" command and wondered why it was taking so long - because I'd forgotten to give it
    the files to search! (That's my fault, not grep's.)


    If grep required additional option for acception of input from stadard
    input that would be [mildly] annoying.




    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Michael S@3:633/10 to All on Sat Sep 19 21:22:51 2026
    On Fri, 18 Sep 2026 15:47:01 GMT
    scott@slp53.sl.home (Scott Lurndal) wrote:

    Michael S <already5chosen@yahoo.com> writes:
    On Fri, 18 Sep 2026 12:55:11 -0000 (UTC)
    cross@spitfire.i.gajendra.net (Dan Cross) wrote:

    In article <118i2mc$q9l1$1@dont-email.me>, bart <bc@freeuk.com>
    wrote:
    On 17/09/2026 23:06, Keith Thompson wrote: =20
    bart <bc@freeuk.com> writes: =20
    On 17/09/2026 08:24, tTh wrote: =20
    On 9/17/26 02:49, bart wrote: =20
    And I've no idea where gcc would look for its headers, other
    than where it keeps its system headers, or how to set it up
    to look permanently in certain places. =20
    =C2=A0=C2=A0 You just have to read the fscking manual.
    https://gcc.gnu.org/onlinedocs/gcc/Environment-Variables.html
    =20

    Nobody uses environment variables any more. =20
    =20
    Obviously untrue. =20

    Let's say they're out of fashion. =20
    =20
    Why would you say such a thing? While they may not be the most
    elegant solution to a number of problems, they're very much in
    use, and "in fashion", at least on Unix-derived systems.
    =20
    - Dan C.
    =20

    Would you design a new program which behavior can be modified by >environment variables? I don't mean standard environment variables,
    like locale (although that is also less than great) but environment >variables specific to your program?


    Absolutely.

    And they would be well documented in the manual page for the program.

    LD_DEBUG, for example, is quite useful in certain usage cases and
    effectively impossible to handle with a command line option flag.

    Why impossible?
    Because devs of gnu ld.so were inconsistent or for other reasons?









    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Michael S@3:633/10 to All on Sat Sep 19 22:01:32 2026
    On Fri, 18 Sep 2026 18:08:38 +0200
    David Brown <david.brown@hesbynett.no> wrote:



    On the other hand, I have a number of times run a "grep" command and wondered why it was taking so long - because I'd forgotten to give it
    the files to search! (That's my fault, not grep's.)


    I don't recollect that it ever happened to me.
    I'd guess the reson is that it only happens when grep is given exactly 1 parameter, whch is less likely to happen by mistake than calling it
    with no parameters.





    --- PyGate Linux v1.5.19
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From bart@3:633/10 to All on Sat Sep 19 20:09:43 2026
    On 19/09/2026 16:27, David Brown wrote:
    On 18/09/2026 21:07, bart wrote:
    On 18/09/2026 16:24, David Brown wrote:
    On 18/09/2026 15:03, bart wrote:

    ˙˙So "gcc" and "as" are wildly different tools that are used in wildly
    different ways, written by completely separate groups of people.˙ The
    fact that they have different defaults is hardly surprising - a
    compiler will rarely be used with piped input from outside, whereas
    for "as", that is by far the most common mode of operation.

    Actually, gcc on Windows seems to generate temporary .s files that are
    submitted to 'as'. Piping isn't used.

    Piping is an option that is used on some systems, and not on others, and
    it can be enabled with "gcc -pipe".˙ Whether you are using a pipe or a temporary file, the prime use of "as" is not as a program run by a user,
    but as a program run by "gcc".


    Both gcc and 'as' take inputs which are one or more files (sequences
    of bytes) and write outputs that are one or more files.

    You probably can't get any simpler than that in a computer program.


    So now gcc is a simple program?

    It's simple in that its job is to convert file A to file B for example.

    But if either seriously expect source code to be entered 'live', then
    they should show a prompt; how hard would that be?

    That's a meaningless question, as the pre-condition is clearly false.

    Steven GK's opening post contained just such an example. I guess as an
    example of how 'useful' the feature is.
    I accept that it is fine for a program to print a quick help message
    when run with incomplete or incorrect arguments.˙ But it is also fine
    for it to give an error message.˙ And for some programs, it can be appropriate to show nothing when given no arguments, or to wait for
    input from stdin.˙ All options are reasonable for some kinds of
    programs.˙ In some programs you wrote, you picked one method, in some programs other people have written, they picked a different solution.
    Your personal opinions do not form the requirements for all the world's software.

    My experience of my developing such tools plus 50 years' experience of
    using tools from non-Unix-like systems.

    So let me be more nuanced - /sometimes/ it is reasonable to concatenate assembly files, and assembly files may be written with that in mind.˙ It
    is almost never reasonable to concatenate C source files.

    For an assembler designed with direct use as a primary aim, you could reasonably pick a different handling of multiple source files - maybe
    they would be assembled independently to generate multiple object files,
    or maybe they would be rejected as invalid use of the assembler (with a nice, friendly help message if you don't like error messages).

    I have two assemblers, AA6 and AA7. Both are designed to process machine-generated inputs, so have no fancy features. Both have a decent
    UI and can be used as command line tools.

    AA6 can take multiple, independent files in any order (but which
    comprise the same program) and produces always one output file (EXE,
    DLL, OBJ etc).

    AA7 takes one input file only (used for whole-program compilers).

    So, these are unusual in integrating 'linking', but the OBJ options
    enables the use of an external linker, while both can be invoked
    per-file generating OBJ format for more conventional use.

    ˙ For an
    assembler designed primarily to be called from a compiler driver
    program,

    If such programs cannot be easily used from a console, then why even
    bother? Just have them as dynamic libraries with an API. The inputs and outputs can be strings instead of files, so you get the advantages of
    piping.


    None of us here wrote any of the tools under discussion.

    Well that is one big difference then because I also write CLI tools.

    There are reasonable uses of files as both executables and libraries.
    Very often in my Python coding, I will have a Python file that is
    intended for use as a "library" (i.e., to be imported from other
    modules, scripts or Python shells) but which can also be run directly
    for test purposes or as simple command-line programs.

    Scripting languages are different: eg. in mine each module can have a
    'main' function that is run if this is the lead module, or ignored
    otherwise.

    (Python will have some means to do that via __main__ etc.)

    Actually I have a similar feature in my systems lang: a subprogram can
    contain its own main() routine which is ignored when it is imported into
    the main app.

    For example, I've given my 'bignum' library a main() routine. I can
    compile and run it by itself:

    c:\mx>mm -r bignum
    Bignum Main # it doesn't do much

    But I can still use it like this within another app:

    import bignum

    The library is still compiled into the EXE (it's not a DLL). However, I
    can't now use:

    module bignum

    since the compiler reports two main() functions.


    ˙ For large enough
    programs, it is normal to separate the dll's from the exe's, but
    combining them in one file would surely suit your preference for minimum number of files.

    The largest DLL on my machine is chrome.dll at about 300MB. It exports
    just 6 functions, to do with starting or restarting Chrome.

    This could reasonably lead people to think that with "-shared", it
    would write a .dll file. They would be wrong.

    So they have to learn how to use their tools.

    They have to learn this dangerous QUIRK. And the people responsible for
    the compiler might think about fixing that quirk.

    (I have much experience of customer support and would see what things
    caused problems. If I just told them to go and read the effing manual as
    many here are keen on, I wouldn't have had many customers left.

    Basically, someone has a task that involves in getting from A to B. They
    don't care how they get there within reason, but which of these is more desirable:

    * Having 6 fiddly, error prone steps together with unfriendly
    advice to RTFM if anyone complains

    * Having only 3 simpler steps and a sympathetic vendor who is willing
    to consider suggestions for further improvement

    Difficult one isn't it? Yet everyone here seems to consider the first
    option is acceptable.)

    C compilers that don't follow gcc (clang follows gcc, and tcc follows
    it on Linux only), tend to take the name of the first submitted C file
    as the default name of the output, when there is one output.


    That seems reasonable for compilation - compiling "file.c" to "file.o".
    gcc does that - "gcc -c file.c" produces "file.o".

    It has to. If:

    gcc -c one.c two.c three.c

    were all written to the same a.out, with each overwriting the last, then
    even gcc knows that would be utterly stupid as well as pointless.


    Generating an exe file, or a shared library, is very likely to involve
    more than one file.˙ Naming the output after one file is therefore not helpful.˙ Naming it "a.out" is not particularly helpful either, but
    that's the tradition.
    Naming it after the first or only file is a more reasonable default than a.out. Since this sequence:

    gcc -shared one.c
    gcc -shared two.c
    gcc -shared three.c

    when you have three libraries would be as nonsensical as the above example.

    Something else which is just plain wrong, and can waste a lot of time.
    When you have to do twice the work of specifying an input, or you may
    have to repeat a lengthy compile if you need to run an earlier, now
    overwritten, a.exe again.


    Again, when you see this as an issue, it is because you are doing things wrong.

    Remember, you are not doing software development here, or doing any programming.˙ You are not writing code and producing executables or libraries.

    Most of my involvement with gcc and 'as' is ad hoc. This is stuff
    outside of a formal project which my IDE would take care of.

    Now, I realise that the way I use my tools and the setups I have is not necessarily typical of anyone else.˙ But a quick check of the command
    line used for each individual compile in my current project shows 111 arguments ( over about 2300 characters.˙ That includes all the include directory flags (blame idiot microcontroller manufacturer SDKs for their necessity, not me or gcc),

    This is another bugbear which you dismissed the other day: the
    desirability of providing compact, production header files that exist in
    one place.

    a couple of dozen specifically chosen
    optimisation flags, a dozen flags for details of the exact target
    processor features, lots and lots of warning flags, and one argument specifying the output file name and directory.˙ For the linking call to
    gcc - the one you are most upset about - there are about 760 arguments
    over 60,000 characters due to the 729 object file names and their directories.

    And this is where my language system has eliminated traditional linking completely.

    ˙ (These are all automatically generated by my makefiles.)
    That's a /real/ project for a /real/ program.

    It sounds like some people over the last few decades should have been
    working on the same lines I have - to simplify all this stuff, rather
    than manage it via extra layers and extra options.

    You know, the sort of thing you describe as 'faffing around'. But
    clearly you don't consider devising and refining language tools to be
    software development.



    ˙ Do you honestly think
    that having a better (IYHO) default choice of output filename would make
    a difference?

    Not everyone works at this level. Lot of people - beginners, hobbyists, experimenters who are not using a fancy IDE will be using the command line.

    And there these quirks can be a very big annoyance. A piece of software
    made a questionable choice in its UI and it would nice if it was fixed.



    --- 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 Sun Sep 20 10:17:41 2026
    On 19/09/2026 20:00, Michael S wrote:
    On Fri, 18 Sep 2026 18:08:38 +0200
    David Brown <david.brown@hesbynett.no> wrote:

    On 18/09/2026 17:34, Michael S wrote:
    On Fri, 18 Sep 2026 15:28:21 GMT
    scott@slp53.sl.home (Scott Lurndal) wrote:

    Michael S <already5chosen@yahoo.com> writes:
    On Thu, 17 Sep 2026 17:50:57 -0700
    Keith Thompson <Keith.S.Thompson+u@gmail.com> wrote:

    bart <bc@freeuk.com> writes:
    On 18/09/2026 01:04, Steven G. Kargl wrote:
    [...]
    Most people read (or at least skim) the documentation
    that comes with the software they use.

    Most people probably don't. They will try running such programs
    without input, as often that gives usage info.

    [...]

    You've seen how that approach fails.

    There are valid reasons for the way "as" behaves.

    Well, if you consider compatibility with weird notion of "user
    interface" of its original creator as a valid reason, then yes.
    Even I accept it as valid.
    Which does not make it less bad in the absolute sense.
    Desire to give to user an option to accept an input from standard
    input by itself is not unreasonable, bit it should be an option
    rather than default.

    That's your opinion. That's not the unix philosophy. Many
    unix commands default to stdin if no file name is specified
    (specifically to support streaming the output of one command
    to the input of another).

    There is big difference between utilities like grep or sort and
    something like as. Blindly treating them as the same is wrong.


    By convention a single dash character may be specified
    in place of a filename to specify stdin.


    The latter is reasonable. What as does is not.


    From the manual page of "as" :

    """
    as is primarily intended to assemble the output of the GNU C compiler
    "gcc" for use by the linker "ld". Nevertheless, we've tried to make
    as assemble correctly everything that other assemblers for the same
    machine would assemble. Any exceptions are documented explicitly.
    This doesn't mean as always uses the same syntax as another assembler
    for the same architecture; for example, we know of several
    incompatible versions of 680x0 assembly language syntax.


    I don't know when this paragraph was written.
    Today's gnu as is pretty reasonable tool for assembler develpment.
    Decent macro capabilities etc... Likely, not on par with
    macro-assemblers of IBM mainframes or of VAX/VMS, but rather similar in capabilities to Microsoft's Masm or with nasm.
    Certainly it is far more complete tool than what would be neeaded to
    process gcc output into objects.

    I also have no idea when it was written, but nothing you wrote
    contradicts it. As I understand it, "as" was originally intended to
    work as the assembler for a compiler, but the developers also saw that
    it could be made useful as a general-purpose stand-alone assembler. It
    may even be the case that they put more effort into coding that aspect
    of its use than handling compiler output. Nonetheless, handling
    compiler output is their stated primary use-case.

    (I've used a lot of different assemblers for microcontrollers through
    the years, but have not used "as" directly in real projects. All my
    targets that have had "as" have also had gcc, and so I programmed in C
    or C++ instead - handling any assembly as inline assembly in C.)



    On the other hand, I have a number of times run a "grep" command and
    wondered why it was taking so long - because I'd forgotten to give it
    the files to search! (That's my fault, not grep's.)


    If grep required additional option for acception of input from stadard
    input that would be [mildly] annoying.


    Agreed. I'd rather occasionally be surprised when I forgot the filename
    than have to add an additional argument when I want to use it as a pipe.


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