• Re: this girl calls c ugly

    From Bart@bc@freeuk.com to comp.lang.c on Fri Jun 5 11:04:51 2026
    From Newsgroup: comp.lang.c

    On 05/06/2026 08:53, Tim Rentsch wrote:
    cross@spitfire.i.gajendra.net (Dan Cross) writes:

    In article <10vsrpo$men2$2@dont-email.me>, Bart <bc@freeuk.com> wrote:

    On 04/06/2026 22:06, Keith Thompson wrote:

    Bart <bc@freeuk.com> writes:

    [snip]
    Tim Rentsch I'm sure will prefer the latter because 99.9% of C
    programmers are machines, according to him.

    Tim didn't say or imply that.

    So what was his 99.9% all about? Nobody has a clue, except they are
    certain that what I think it is is wrong!

    Have you thought about, I don't know, maybe asking him?

    Asking him straight questions is usually futile. You can probably guess
    this from the response below.

    Notice he hasn't tried to enlighten anyone about that 99.9%.

    That may just have been a throwaway line like when I say 'nobody likes
    X', but I would still dispute that, if it's about what I think it is,
    it's anything like a super-majority.


    At the risk of saying what may be obvious to everyone, Bart has
    shown that he has no interest in having a serious, constructive,
    useful, or productive conversation with anyone. His questions
    are all rhetorical; he hasn't asked me a straight question
    because he isn't really interested in what I would say. In
    short, Bart isn't looking for an answer, he's looking for an
    argument. My recommendation is just stop responding to him
    altogether. My response to him upthread was a sincere effort to
    provide a neutral and helpful answer to his question. Maybe my
    remarks were helpful to other people, and if they were that's
    good. Any further efforts to interact with Bart are not just a
    waste of time but actually counterproductive. What Bart needs is
    not help with understanding C but a good therapist. In any case
    I'm confident that whatever Bart's needs may be, no one responding
    to his postings here is in a position to provide them. Please
    consider these remarks before responding to him further.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Bart@bc@freeuk.com to comp.lang.c on Fri Jun 5 12:39:43 2026
    From Newsgroup: comp.lang.c

    On 05/06/2026 08:29, David Brown wrote:
    On 04/06/2026 21:29, Bart wrote:

    You're saying that:

    How can this be /so/ difficult for you?


    *-a "more than needed" is objective

    No, I said that "(a*a) + (b*b)" has more parentheses than needed in the context of most programming languages" is objective.

    *-a "too many" is subjective

    No, I said that "(a*a) + (b*b) has too many parentheses" is subjective.

    If anyone is interested (which I doubt; bart-bashing is much more fun),
    this is the original context:

    TR:
    Sadly the idea of writing in a way that is "most easily understood"
    has resulted in a race to the bottom, where writers are more and
    more encouraged to take the view that (some) readers are pretty
    much arbitrarily stupid, with the result that expressions become
    littered with scads of unnecessary parentheses that actually
    detract from ease of reading. Good writing is always a balance
    between too much and too little.

    BC:
    Actual examples of too many parentheses?

    TR:
    The point of my comment is that either too many or too few is a
    subjective judgment, not an objective one.

    Here it is clear that 'too many' was just a paraphrase of 'unnecessary'.
    Here is my followup to TR:

    BC:
    My point was that it could be objective, at least for too many.

    For an infix syntax where * has higher priority than +, then it is a
    fact that the () in (a*a) + (b*b) are not necessary.

    So, assume a minimum number of () needed to properly parse an expression according to intent. Then:

    (1) TOO FEW: necessarily has to be subjective. It suggests a desire for
    more () than the minimum, but the exact number will vary.

    (2) TOO MANY, MORE THAN NEEDED, ETC: These can objective if refering to
    any number of extra () above the mininum. This is the point I made
    above, the one I defended.

    (3) TOO MANY, MORE THAN NEEDED, ETC: These can also be used in a
    judgemental manner, and there are subjective. This is where a certain
    number of extra () are accepted for readability etc, but the exact level
    will vary.

    If this is the point people have been trying to make, then they've been
    doing it incredibly badly, and been unnecessarily unpleasant and insulting.

    My own view is that C syntax has too much of (3), but necessarily so
    because of the choices made in its operator levels.

    The syntaxes I work on tend to have more of (2); () is less often needed
    for readability because of more sensible design choices. And IMO less
    often needed for overrides too, for the same reasons.

    For example, where C has (*P).m or (*Q)[i], I'd write P^.m or Q^[i],
    since I chose a postfix rather then prefix deferences operator.

    In general, for the same programs, C will probably use at least 20% more parentheses.



    Tim Rentsch I'm sure will prefer the latter because 99.9% of C
    programmers are machines, according to him.

    Please give a reference for him saying that.-a (I'll save you the bother,
    he has not made any remarks remotely like this in c.l.c. since I have
    been here.)

    Find out what was the subject of the 99.9% (even if that was an
    exaggeration). Then we'll talk.

    No, he didn't use the word 'machines'; I paraphrased to suggest
    supernormal people who know everything and never make mistakes.

    You're going to argue about this now?


    Presumably, the same 99.9% will not use indentation, and will write
    their programs all on one line anyway, because it is still after all
    completely unambiguous according to the C standard!

    Don't presume - you make a fool out of yourself every time you do.

    And you proceed to do exactly the same; Bart must be wrong, but you
    don't about what!


    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Tim Rentsch@tr.17687@z991.linuxsc.com to comp.lang.c on Fri Jun 5 05:34:20 2026
    From Newsgroup: comp.lang.c

    I didn't read Bart's posting. Unfortunately it seems
    true that any continued interaction with his comments
    is counterproductive.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Tim Rentsch@tr.17687@z991.linuxsc.com to comp.lang.c on Fri Jun 5 05:49:58 2026
    From Newsgroup: comp.lang.c

    Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:

    James Kuyper <jameskuyper@alumni.caltech.edu> writes:
    [...]

    One advantage of having a single program do the whole thing, is
    that error messages can mention the actual text of the line where
    a problem was detected, without any pre-processing applied.

    Typical preprocessors emit directives that tell the compiler
    about the current file name and line number, precisely so that
    diagnostic messages can refer to the original text.

    For example:

    $ cat hello.c
    #include <stdio.h>
    int main(void) {
    printf("Hello world!\n");
    }
    $ gcc -E hello.c | tail
    extern int __uflow (FILE *);
    extern int __overflow (FILE *, int);
    # 983 "/usr/include/stdio.h" 3 4

    # 2 "hello.c" 2

    # 2 "hello.c"
    int main(void) {
    printf("Hello world!\n");
    }
    $

    The line `# 2 "hello.c"` is, according to the C standard, a
    "non-directive", which is a kind of directive. Executing a
    non-directive has undefined behavior,

    Since it is gcc that is generating the non-directives, for
    internal purposes, and gcc that is consuming them, it hardly
    seems worth worrying about whether their behavior is defined
    or not.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From antispam@antispam@fricas.org (Waldek Hebisch) to comp.lang.c on Fri Jun 5 12:58:34 2026
    From Newsgroup: comp.lang.c

    Chris M. Thomasson <chris.m.thomasson.1@gmail.com> wrote:
    On 6/4/2026 4:44 PM, Bart wrote:
    On 05/06/2026 00:09, Keith Thompson wrote:
    Bart <bc@freeuk.com> writes:
    On 04/06/2026 22:06, Keith Thompson wrote:
    Bart <bc@freeuk.com> writes:
    On 04/06/2026 19:54, David Brown wrote:
    [...]
    Again - /please/ stop trying to guess what people say or put words >>>>>>> in their mouths.-a I can't remember ever seeing you do so accurately. >>>>>>
    This is what you actually said:

    It is an objective fact, therefore, that "(a*a) + (b*b)" has more >>>>>>> parentheses than needed in the context of most programming languages. >>>>>>>
    "(a*a) + (b*b) has too many parentheses", on the other hand, is a >>>>>>> purely
    subjective opinion.-a Even if it is true that this is "commonly agreed >>>>>>> to" (and AFAIK you have no basis for that claim), that would still >>>>>>> be a
    subjective opinion - no matter how common that opinion is.

    You're saying that:

    *-a "more than needed" is objective
    *-a "too many" is subjective
    Stop it.-a He's not saying that.

    That is EXACTLY what he's saying: "It is an OBJECTIVE fact .. has more >>>> ... than needed", and:

    -a "has too many ... is ... purely subjective".

    You're taking phrases out of context and making false claims that the >>>>> full statement was far more general than it actually was.

    And this is exactly what other people are doing.

    Taken literally, your statement implies that you admit that that's
    what you're doing.-a Is that what you meant?-a If so, I suggest you
    *stop* making such false claims.-a If not, what did you actually mean?

    So I used TOO MANY instead of MORE THAN NEEDED to describe the exact
    same phenomenon.

    That's not the problem.-a There is an actual meaningful distinction
    here, between what's needed by the compiler and what's useful to
    improve clarity for human readers.-a I have found some of what you've
    written to be unclear about that distinction.

    Can we agree that the question of whether parentheses in a C
    expression are necessary to the compiler can be answered objectively?
    Can we agree that the question of whether extra parentheses are
    helpful to a human reader is at least partly subjective, and
    varies from case to case?-a Is there really anything else that we
    fundamentally disagree about?

    (1) Why are you all making such a big fucking deal of this?

    Why are you?

    I didn't start this business of something being subjective or objective,
    or suggesting than one turn of phrase to discuss the same thing was
    subjective and the other objective (implying that a subjective opinion
    had less worth). TR started that and several people backed him up.

    Myself I wouldn't even use those terms. My point was that some overuses
    of () for commonly known precedences are more overkill than others.

    If that's subjective then so be it; it is not some fundamental law of
    the universe. I would just call it common sense.

    Why are you?

    Since you ask, I was defending my point of view then got sidetracked by
    this subjective/objective nonsense. I notice that TR has disappeared
    from this subthread.


    Wrt the number of ()'s? Might as well go to sleep with the following
    song playing in the background:

    (The Fate of Ophelia - Taylor Swift (Lyrics) Charlie Puth ft. Selena
    Gomez, the weekd, ariana grande)

    AFAICS outer parentheses there are excessive, inner ones look OK.
    --
    Waldek Hebisch
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From David Brown@david.brown@hesbynett.no to comp.lang.c on Fri Jun 5 15:42:59 2026
    From Newsgroup: comp.lang.c

    On 05/06/2026 13:39, Bart wrote:
    On 05/06/2026 08:29, David Brown wrote:
    On 04/06/2026 21:29, Bart wrote:

    You're saying that:

    How can this be /so/ difficult for you?


    *-a "more than needed" is objective

    No, I said that "(a*a) + (b*b)" has more parentheses than needed in
    the context of most programming languages" is objective.

    *-a "too many" is subjective

    No, I said that "(a*a) + (b*b) has too many parentheses" is subjective.

    If anyone is interested (which I doubt; bart-bashing is much more fun),
    this is the original context:


    I am writing in a detailed and repetitive maner to be sure there are no misunderstandings, not as "bart-bashing".

    TR:
    Sadly the idea of writing in a way that is "most easily understood"
    has resulted in a race to the bottom, where writers are more and
    more encouraged to take the view that (some) readers are pretty
    much arbitrarily stupid, with the result that expressions become
    littered with scads of unnecessary parentheses that actually
    detract from ease of reading.-a Good writing is always a balance
    between too much and too little.


    This is clearly about "too many" or "too few" as a subjective matter -
    i.e., in addition to the minimum required for the desired semantics.
    (The minimum requirements are objective, so the code has the correct C semantics - additional parentheses are about style and clarity, which
    are subjective.)

    BC:
    Actual examples of too many parentheses?

    I assume here we are again talking about "too many" beyond the necessary number. Coming from anyone else, I would happily assume they are
    talking about subjective opinions - "Can you give examples of real-world
    code where you think there are too many unnecessary parentheses,
    resulting in code that is harder to read than it would otherwise be?"
    Coming from you, it might also mean the nonsensical question "Can you
    give examples of code that objectively has too many unnecessary
    parentheses?".


    TR:
    The point of my comment is that either too many or too few is a
    subjective judgment, not an objective one.

    Here it is clear that 'too many' was just a paraphrase of 'unnecessary'.

    No, it is not. In the expression "a << (b + c)", there are unnecessary parentheses, but not - IMHO - too many parentheses. That is because "unnecessary" (in this context - and don't generalise from it) is an
    objective matter of whether or not the semantics of the expression are affected by the parentheses. "Too many" (in this context) is a
    subjective matter of clarity of code. In my opinion, the parentheses
    are helpful and there are therefore not too many of them - but as a
    matter of C semantics, they are objectively unnecessary.

    Again, I am unable to read Tim's mind, and I am not accountable for what
    he writes or how he writes it. But to my reading, it is quite clear
    that "too many" is /not/ a paraphrase of "unnecessary".

    Here is my followup to TR:

    BC:
    My point was that it could be objective, at least for too many.


    Yes, you wrote that. You are wrong. At least, you are wrong until
    someone exceeds the 63 levels of nesting that are required to be
    supported by conforming compilers, but I do not believe that is
    something you are considering.

    For an infix syntax where * has higher priority than +, then it is a
    fact that the () in (a*a) + (b*b) are not necessary.

    Agreed.


    So, assume a minimum number of () needed to properly parse an expression according to intent. Then:

    No, don't assume that. "Intent" implies reading the mind of the
    programmer. There is no such thing as "obvious intent" - there is the objective semantics of what the programmer writes, and the subjective
    ease with which people (including the programmer himself/herself) can
    read the code and understand the semantics of it. The former depends
    solely on the code written, the later depends significantly on the
    people reading it.

    Let us rather assume a minimum number of parentheses so that removing
    any would change the semantics of the expression. That is an objective measure.


    (1) TOO FEW: necessarily has to be subjective. It suggests a desire for
    more () than the minimum, but the exact number will vary.


    Agreed. (And we would both share the opinion that "a << b + c" has too
    few parentheses because we would feel it is easier to read with more parentheses - while we would both think that "a * a + b * b" does not
    have too few.)

    (2) TOO MANY, MORE THAN NEEDED, ETC: These can objective if refering to
    any number of extra () above the mininum. This is the point I made
    above, the one I defended.

    Nope.

    "a << (b + c)" has "more than needed" - that is objective.

    "a << (b + c)" does not have "too many" in an objective sense, because
    the extra parentheses have not affected any objective characteristic of
    the expression - the semantics are the same. Some people may
    subjectively feel there are "too many" because they think "a << b + c"
    is clearer - others will have different subjective opinions.


    That is the context of the phrases we have had, and how they have been used.

    Terms like "too many" or "more than needed" can be used in different
    contexts, and have different meanings. If you have a bowl that can hold
    6 apples, and you try to put 10 apples in the bowl, that is objectively
    "too many". If you write "that expression has more parentheses than
    needed to make the meaning clear to readers", then that is a subjective
    claim - it does not say anything about the number of parentheses needed
    to express the semantics in C (that's objective), but talks about the subjective views of readers.

    You cannot take a phrase like these and say "this is always objective"
    or "this is always subjective" - the context is always critical.


    (3) TOO MANY, MORE THAN NEEDED, ETC: These can also be used in a
    judgemental manner, and there are subjective. This is where a certain
    number of extra () are accepted for readability etc, but the exact level will vary.

    If this is the point people have been trying to make, then they've been doing it incredibly badly, and been unnecessarily unpleasant and insulting.


    I cannot speak for the intentions of others, but it has certainly been
    very frustrating trying to get you to understand the distinction between objective facts and subjective opinions, and trying to get you to stop re-writing other people's words and to stop taking partial quotations
    out of context and wildly and inaccurately generalising them.

    My own view is that C syntax has too much of (3), but necessarily so
    because of the choices made in its operator levels.

    That's a subjective opinion. I would agree with it, to at least some
    extent - some of the precedence order is not as I would have picked.
    But given that there are situations where I would include additional parentheses in C code despite agreeing with the precedence order, I
    don't think the C syntax rule choices are the issue. I don't believe I
    would use fewer parentheses even if << and >> had the same precedence
    level as * and /, or if the bitwise operators had higher precedence than equality and other relational operators.


    Tim Rentsch I'm sure will prefer the latter because 99.9% of C
    programmers are machines, according to him.

    Please give a reference for him saying that.-a (I'll save you the
    bother, he has not made any remarks remotely like this in c.l.c. since
    I have been here.)

    Find out what was the subject of the 99.9% (even if that was an exaggeration). Then we'll talk.

    Again, I am not responsible for what Tim (or anyone else) writes. If
    you have asked him for clarification, and he has not given a
    satisfactory answer, there's little more to do.


    No, he didn't use the word 'machines'; I paraphrased to suggest
    supernormal people who know everything and never make mistakes.

    You're going to argue about this now?

    Normally there is nothing wrong with paraphrasing, though in this
    discussion it would make a lot more sense to be precise about
    quotations. However, wildly exaggerating what someone says is not "paraphrasing". It is misrepresenting them, and is dishonest when done intentionally and knowingly.



    Presumably, the same 99.9% will not use indentation, and will write
    their programs all on one line anyway, because it is still after all
    completely unambiguous according to the C standard!

    Don't presume - you make a fool out of yourself every time you do.

    And you proceed to do exactly the same; Bart must be wrong, but you
    don't about what!


    I am not presuming - I was making a comment based on past history. It
    would be nice if it changed, either because you stop trying to guess
    what people think or might say, and stop distorting what they write.
    Put a bit more effort into reading peoples posts, and less effort into
    the paranoia, and I'm sure you'll feel the threads are more productive.


    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From scott@scott@slp53.sl.home (Scott Lurndal) to comp.lang.c on Fri Jun 5 14:04:19 2026
    From Newsgroup: comp.lang.c

    cross@spitfire.i.gajendra.net (Dan Cross) writes:
    In article <1BoUR.3$lmCb.1@fx22.iad>, Scott Lurndal <slp53@pacbell.net> wrote: >>cross@spitfire.i.gajendra.net (Dan Cross) writes:
    [snip]
    <snip>
    Yeah, that's from `cc.c`, right?

    No, it's from cpp.c

    $ ls /work/reference/collegetapes/sltape/v6cc/
    c0.c c00.c c01.c c02.c c03.c c04.c c05.c c1.h
    c10.c c11.c c12.c c13.c c2.h c20.c c21.c cc.c cpp.c

    Oh interesting. I don't have a `cpp.c` in my v6 archive.

    I wonder what else I'm missing.

    For your archive, cpp.c

    #
    # include <stdio.h>
    /* C command */

    # define SBSIZE 15000
    # define SYMSIZ 1500
    # define TOKLEN 16
    # define DROP (-2)
    # define SAME 0
    # define MAXINC 10
    char sbf[SBSIZE];
    # define CHSPACE 1000
    char ts[CHSPACE+50];
    # define EXPSIZE 500
    char *strdex(), *copy(), *calloc(), *token(), *coptok();
    char *tsa ts;
    char *tsp ts;
    char *fnames[MAXINC];
    # define LINELEN 512
    FILE *fin;
    FILE *fout;
    int instring;
    char direct[50];
    int nd 1;
    char *dirs[10] {direct, 0};
    char nfil[100];
    int pflag;
    int depth;
    int skipcom;
    FILE *fins[MAXINC];
    int ifno;
    char *lp;
    char *line;
    # define NPREDEF 20
    char *prespc[NPREDEF];
    char **predef prespc;
    char *punspc[NPREDEF];
    char **prund punspc;
    char **predp;
    int lineno[MAXINC];
    int exfail;
    struct symtab {
    char name[TOKLEN];
    char *value;
    } *symtab, *lookup();
    struct symtab *defloc;
    struct symtab *udfloc;
    struct symtab *incloc;
    struct symtab *ifloc;
    struct symtab *elsloc;
    struct symtab *eifloc;
    struct symtab *ifdloc;
    struct symtab *ifnloc;
    struct symtab *sysloc;
    struct symtab *lneloc;
    struct symtab *prdloc;
    int trulvl;
    int flslvl;
    char *stringbuf;

    mainpp(argc,argv)
    char *argv[];
    {
    int i;
    # ifdef tgp
    int ifbrk;
    # endif
    char ln[LINELEN];
    register int c;
    register char *rlp;
    char *sp;
    struct symtab stab[SYMSIZ];

    fin = stdin;
    fout = stdout;
    # ifdef unix
    fnames[ifno=0] = "";
    # endif
    # ifdef gcos
    fnames[ifno=0] = "s*";
    # endif
    # ifdef ibm
    fnames[ifno=0] = "";
    # endif
    for(i=1; i<argc; i++)
    {
    switch(argv[i][0])
    {
    case '-':
    switch(argv[i][1])
    {
    case 'P':
    pflag++;
    case 'E':
    continue;
    case 'D':
    if (predef>prespc+NPREDEF)
    {
    error("too many -D options, ignoring %s",argv[i]);
    continue;
    }
    *predef++ = argv[i]+2;
    continue;
    case 'U':
    if (prund>punspc+NPREDEF)
    {
    error("too many -U options, ignoring %s",argv[i]);
    continue;
    }
    *prund++ = argv[i]+2;
    continue;
    case 'I':
    if (nd>8)
    error("excessive -I file (%s) ignored",argv[i]);
    else
    dirs[nd++] = argv[i]+2;
    continue;
    case '\0': continue;
    default:
    error("unknown flag %s", argv[i]);
    continue;
    }
    default:
    if (fin==stdin)
    {
    fin = fopen(argv[i], "r");
    if (fin==NULL)
    {
    error("No source file %s",argv[i]);
    exit(8);
    }
    fnames[ifno]=argv[i];
    strcpy(direct, argv[i]);
    for(sp=direct; *sp; sp++);
    while (sp>direct && *sp != '/') sp--;
    # ifdef unix
    if (sp==direct)
    *sp++ = '.';
    # endif
    *sp=0; /* direct now has place where source file is */
    }
    else
    if (fout==stdout)
    {
    fout= fopen(argv[i], "w");
    if (fout==NULL)
    {
    error("Can't write %s", argv[i]);
    exit(8);
    }
    }
    else
    error("extraneous name %s", argv[i]);
    }
    }

    fins[ifno]=fin;
    exfail = 0;
    /* after user -I files here are the standard include libraries */
    # ifdef unix
    dirs[nd++] = "/usr/include";
    # endif
    # ifdef gcos
    dirs[nd++] = "cc";
    # endif
    # ifdef ibm
    dirs[nd++] = "stdio.";
    # endif
    /* dirs[nd++] = "/compool"; */
    dirs[nd++] = 0;
    symtab = stab;
    for (c=0; c<SYMSIZ; c++) {
    stab[c].name[0] = '\0';
    stab[c].value = 0;
    }
    insym(&defloc, "define");
    insym(&udfloc, "undef");
    insym(&incloc, "include");
    insym(&elsloc, "else");
    insym(&eifloc, "endif");
    insym(&ifdloc, "ifdef");
    insym(&ifnloc, "ifndef");
    insym(&ifloc, "if");
    # ifdef unix
    insym(&sysloc, "unix");
    # endif
    # ifdef gcos
    insym (&sysloc, "gcos");
    # endif
    # ifdef ibm
    insym (&sysloc, "ibm");
    # endif
    insym(&lneloc, "line");
    predp=predef;
    while (predp>prespc)
    if (sp=strdex(*--predp, '='))
    {
    *sp++=0;
    stsym(*predp, sp);
    }
    else
    insym(&prdloc, *predp);
    predp=prund;
    while (predp>punspc)
    {
    if (sp=strdex(*--predp, '='))
    *sp++=0;
    lookup(*predp, DROP);
    }
    stringbuf = sbf;
    trulvl = 0;
    flslvl = 0;
    line = ln;
    lineno[0] = 1;
    if (pflag==0) fprintf(fout, "# 1 \"%s\"\n", fnames[ifno]);
    while(getline()) {
    skipcom=0;
    if (ln[0] != '#' && flslvl==0)
    {
    # ifdef tgp
    ifbrk= checklen(line);
    # endif
    for (rlp = line; c = *rlp++;)
    putc(c, fout);
    # ifdef tgp
    if (ifbrk)
    fprintf(fout,"\n# %d",lineno[ifno]);
    # endif
    }
    putc('\n', fout);
    }
    # ifdef tgp
    checklen(line);
    # endif
    for(rlp=line; c = *rlp++;)
    putc(c,fout);
    }

    getline()
    {
    register int c, sc, state;
    struct symtab *np;
    char *namep, *filname, **dirp;
    int filok, inctype;

    lp = line;
    *lp = '\0';
    state = 0;
    if ((c=getch()) == '#')
    state = 1;
    while (c!='\n' && c!='\0') {
    if (letter(c)) {
    namep = lp;
    sch(c);
    while (letnum(c=getch()))
    sch(c);
    sch('\0');
    lp--;
    if (state==6)
    {
    lookup(namep, DROP);
    goto out;
    }
    if (state>3 && state <6) {
    if (flslvl==0 &&(state+!lookup(namep,-1)->name[0])==5)
    trulvl++;
    else
    flslvl++;
    out:
    while (c!='\n' && c!= '\0')
    c = getch();
    return(c);
    }
    if (state==3) /* include */
    if (*namep != '"' && *namep != '<')
    {
    error("Bad include syntax", 0);
    state=1;
    }
    if (state!=2 || flslvl==0)
    {
    pushback(c);
    np = lookup(namep, state);
    c = getch();
    }
    if (state==1) {
    if (np==defloc)
    skipcom = state = 2;
    else if (np==incloc)
    state = 3;
    else if (np==ifnloc)
    state = 4;
    else if (np==ifdloc)
    state = 5;
    else if (np==eifloc) {
    if (flslvl)
    --flslvl;
    else if (trulvl)
    --trulvl;
    else errback("If-less endif",0);
    goto out;
    }
    else if (np==elsloc) {
    if (flslvl)
    --flslvl? ++flslvl : ++trulvl;
    else if (trulvl)
    {++flslvl; --trulvl;}
    else
    errback("If-less else",0);
    goto out;
    }
    else if (np==udfloc) {
    state=6;
    }
    else if (np==ifloc) {
    /*
    if (flslvl ==0 && yyparse())
    */ error("IF not implemented, true assumed",0); if (1)
    trulvl++;
    else
    flslvl++;
    return('\n');
    }
    else if (np==lneloc)
    {
    if(pflag==0) fprintf(fout, "# ");
    lp=line;
    for(; c !='\n' && c != '\0'; c=getch())
    if (!pflag)
    sch(c);
    sch('\0');
    return(c);
    }
    else {
    errback("Undefined control",0);
    while (c!='\n' && c!='\0')
    c = getch();
    return(c);
    }
    } else if (state==2) {
    if (flslvl)
    goto out;
    np->value = stringbuf;
    if (c != '\n' && c != 0)
    {
    savch(c);
    while ((c=getch())!='\n' && c!='\0')
    {
    if (c== '\\')
    {
    c = getch();
    if (c=='\n')continue;
    savch('\\');
    }
    savch(c);
    }
    }
    savch('\0');
    return(1);
    }
    continue;
    } else if ((sc=c) == '\'' || sc== '"' || (state==3 && sc== '<')) {
    sch(sc);
    filname = lp;
    inctype = sc=='<';
    if (sc== '<')
    {
    /*
    fprintf(fout==stdout?stderr:stdout, "note: include <> obsolete, use \"\"\n");
    */
    sc= '>';
    }
    instring++;
    while ((c=getch())!=sc && c!='\n' && c!='\0') {
    sch(c);
    if (c=='\\')
    sch(getch());
    }
    instring = 0;
    if (flslvl)
    goto out;
    if (state==3) {
    if (flslvl)
    goto out;
    *lp = '\0';
    while ((c=getch())!='\n' && c!='\0');
    if (ifno+1 >=MAXINC)
    error("Unreasonable include nesting",0);
    filok=0;
    for(dirp=dirs+inctype; *dirp; dirp++)
    {
    if (filname[0]=='/' || **dirp=='\0')
    strcpy(nfil,filname);
    else
    {
    strcpy(nfil,*dirp);
    # ifdef unix
    strcat(nfil, "/");
    # endif
    # ifdef gcos
    strcat(nfil, "/");
    # endif
    # ifdef ibm
    strcat(nfil, ".");
    # endif
    strcat(nfil, filname);
    }
    if ( (fins[ifno+1]=fopen(nfil, "r"))!=NULL)
    {
    filok=1;
    fin = fins[++ifno];
    break;
    }
    }
    if (filok==0)
    errback("Can't find include file %s", filname);
    else
    {
    if (pflag==0) fprintf(fout, "\n# 1 \"%s\"", filname);
    lineno[ifno]=1;
    fnames[ifno] = copy(filname);
    }
    return(c);
    }
    }
    sch(sc=c);
    c = getch();
    if (isdigit(sc))
    {
    for (;isalpha(c) || isdigit(c); c=getch())
    sch(c);
    }
    }
    sch('\0');
    if (state>1)
    errback("Control syntax",0);
    return(c);
    }
    insym(sp, namep)
    struct symtab **sp;
    char *namep;
    {
    register struct symtab *np;
    *sp = np = lookup(namep, 1);
    np -> value = np -> name;
    }

    stsym(namep, valp)
    char *namep, *valp;
    {
    register struct symtab *np;

    np = lookup(namep, 1);
    value = valp;
    }

    error(s, x)
    char *s;
    {
    FILE *efout;
    efout = fout==stdout ? stderr : stdout;
    if (fnames[ifno][0])
    fprintf(efout,"%s: %d: ", fnames[ifno], lineno[ifno]);
    fprintf(efout, s, x);
    putc('\n',efout);
    exfail++;
    }
    errback(s,x)
    char *s;
    {
    lineno[ifno]--;
    error(s,x);
    lineno[ifno]++;
    }

    sch(c)
    {
    register char *rlp;

    rlp = lp;
    if (rlp==line+LINELEN-2)
    error("Line overflow", 0);
    *rlp++ = c;
    if (rlp>line+LINELEN-1)
    rlp = line+LINELEN-1;
    lp = rlp;
    }

    savch(c)
    {
    *stringbuf++ = c;
    if (stringbuf-sbf < SBSIZE)
    return;
    error("Too much defining", 0);
    exit(exfail);
    }

    getch()
    {
    register int c, lastst;

    while ((c=getc1())=='/' && !instring)
    {
    if ((c=getc1())!='*')
    {
    pushback(c);
    return('/');
    }
    if (!skipcom)
    {putc('/',fout); putc('*', fout);}
    lastst=0;
    while ( (c = getc1()) != '\0')
    {
    if (lastst && c=='/')
    {
    if (!skipcom)
    putc('/', fout);
    break;
    }
    if (c=='\n' || !skipcom)
    putc(c, fout);
    lastst = (c=='*');
    }
    if (c=='\0')break;
    }
    return(c);
    }
    char pushbuff[EXPSIZE];
    char *pushp pushbuff;
    pushback(c)
    {
    *++pushp = c;
    if (pushp>pushbuff+EXPSIZE) {
    error("too much backup", 0);
    exit(8);
    }
    }

    getc1()
    {
    register c;

    if (*pushp !=0)
    return(*pushp--);
    depth=0;
    if ((c = getc(fin)) == EOF && ifno>0) {
    fclose(fin);
    fin = fins[--ifno];
    if (pflag==0) fprintf(fout, "\n# %d \"%s\"\n",lineno[ifno], fnames[ifno]);
    c = getc1();
    if (c=='\n') lineno[ifno]--;
    }
    if (c==EOF)
    return(0);
    if (c=='\n' )
    lineno[ifno]++;
    return(c);
    }

    struct symtab *
    lookup(namep, enterf)
    char *namep;
    {
    register char *np, *snp;
    register struct symtab *sp;
    int i, c, around;
    np = namep;
    snp = np+TOKLEN;
    around = i = 0;
    while ( (c = *np++ ) && (np-snp)<0)
    {
    i =+ c;
    }
    i =% SYMSIZ;
    sp = &symtab[i];
    while (sp->name[0]) {
    if (sp->name[0] != DROP)
    {
    snp = sp->name;
    np = namep;
    while (*snp++ == *np)
    if (*np++ == '\0' || np==namep+TOKLEN) {
    if (enterf==DROP)
    {
    sp->name[0]= DROP;
    return(sp);
    }
    if (!enterf)
    subst(namep, sp);
    return(sp);
    }
    }
    if (++sp >= &symtab[SYMSIZ])
    if (around++)
    {
    error("too many defines", 0);
    exit(exfail);
    }
    else
    sp = symtab;
    }
    if (enterf>0) {
    snp = namep;
    for (np = &sp->name[0]; np < &sp->name[TOKLEN];)
    if (*np++ = *snp)
    snp++;
    }
    return(sp);
    }
    char revbuff[200], *bp;
    backsch(c)
    {
    if (bp-revbuff > 200)
    error("Excessive define looping", bp--);
    *bp++ = c;
    }

    subst(np, sp)
    char *np;
    struct symtab *sp;
    {
    register char *vp;
    int macflg;

    lp = np;
    bp = revbuff;
    if (depth++>100)
    {
    error("define recursion loop on %s", np);
    return;
    }
    if ((vp = sp->value) == 0)
    return;
    macflg= (*vp == '(');
    /* arrange that define unix unix still
    has no effect, avoiding rescanning */
    while (blank(*vp))
    vp++;
    if (strcmp(sp->name,vp) == SAME)
    {
    while (*vp)
    sch(*vp++);
    return;
    }
    if (macflg)
    expdef(vp);
    else
    while (*vp)
    backsch(*vp++);
    while (bp>revbuff)
    pushback(*--bp);
    }




    char *
    copy(as)
    char as[];
    {
    register char *otsp, *s;
    int i;

    otsp = tsp;
    s = as;
    while(*tsp++ = *s++);
    if (tsp >tsa+CHSPACE)
    {
    # ifdef unix
    tsp = tsa = i = calloc(CHSPACE+50,sizeof(char));
    if (i== NULL)
    # endif
    {
    error("no space for file names", 0);
    exit(8);
    }
    }
    return(otsp);
    }


    expdef(proto)
    char *proto;
    {
    char buffer[EXPSIZE], *parg[20], *pval[20], name[20], *cspace, *wp;
    char protcop[EXPSIZE], *pr;
    int narg, k, c;
    pr = protcop;
    while (*pr++ = *proto++)
    if (pr>=protcop+EXPSIZE){
    error("define prototype too big", 0);
    exit(8);
    }
    proto= protcop;
    for (narg=0; (parg[narg] = token(&proto)) != 0; narg++)
    ;
    /* now scan input */
    cspace = buffer;
    while ((c=getch()) == ' ');
    if (c != '(')
    {
    error("defined function requires arguments", 0);
    return;
    }
    pushback(c);
    for(k=0; pval[k] = coptok(&cspace, buffer+EXPSIZE); k++);
    if (k!=narg)
    {
    error("define argument mismatch");
    return;
    }
    while (c= *proto++)
    {
    if (!letter(c))
    backsch(c);
    else
    {
    wp = name;
    *wp++ = c;
    while (letnum(*proto))
    *wp++ = *proto++;
    *wp = 0;
    for (k=0; k<narg; k++)
    if(strcmp(name,parg[k]) == SAME)
    break;
    wp = k <narg ? pval[k] : name;
    while (*wp) backsch(*wp++);
    }
    }
    }

    char *
    token(cpp) char **cpp;
    {
    char *val;
    int stc;
    stc = **cpp;
    *(*cpp)++ = '\0';
    if (stc==')') return(0);
    while (**cpp == ' ') (*cpp)++;
    for (val = *cpp; (stc= **cpp) != ',' && stc!= ')'; (*cpp)++)
    {
    if (!letnum(stc) || (val == *cpp && !letter(stc)))
    {
    error("define prototype argument error");
    return(0);
    }
    }
    return(val);
    }

    char *
    coptok (cpp, clim) char **cpp, *clim;
    {
    char *val;
    int stc, stop,paren;
    paren = stop = 0;
    val = *cpp;
    if (getch() == ')')
    return(0);
    while (((stc = getch()) != ',' && stc != ')' ) || paren > 0 || stop >0)
    {
    if (stc == '\0')
    {
    error("non terminated macro call", 0);
    val = 0;
    break;
    }
    if (stop == 0 && (stc == '"' || stc == '\''))
    stop = stc;
    else if (stc==stop)
    stop=0;
    if ( stc == '\\')
    {
    stc = getch();
    if (stop>0 || (stc != ',' && stc != '\\'))
    *(*cpp)++ = '\\';
    *(*cpp)++ = stc;
    }
    else
    {
    *(*cpp)++ = stc;
    if (stop==0)
    {
    if (stc == '(')
    paren++;
    if (stc == ')')
    paren--;
    }
    }
    if (*cpp >= clim)
    {
    error("define argument too long",0);
    exit(8);
    }
    }
    *(*cpp)++ = 0;
    pushback(stc);
    return(val);
    }
    letter(c)
    {
    if (isalpha(c) || c == '_')
    return (1);
    else
    return(0);
    }
    letnum(c)
    {
    if (letter(c) || isdigit(c))
    return(1);
    else
    return(0);
    }


    blank(c)
    {
    return(c==' ' || c== '\t');
    }

    char *
    strdex(s,c)
    char *s;
    {
    while (*s)
    if (*s==c)
    return(s);
    else
    s++;
    return(0);
    }
    # ifdef tgp
    # define MAXOUT 80
    checklen(sln)
    char *sln;
    {
    /* for tgp: scans string sln, and puts in newlines for blanks,
    where it likes, but to make lines less than MAXOUT chars long */

    char *p, *s, *st;
    int stopc, back, ifdone, c;
    st=s=sln;
    ifdone=p=stopc=back=0;
    while (c= *s++)
    {
    if (c == '\\')
    back=2;
    if (back==0)
    {
    if (stopc== c)
    stopc=0;
    else
    if (c == '"' || c == '\'')
    stopc= c;
    }
    if (back>0)back--;
    if (s-st >MAXOUT && p != 0)
    {
    st=p;
    *p= '\n';
    ifdone=1;
    }

    if (stopc==0 && back==0)
    if (c==' ') p=s-1;;
    }
    return(ifdone);
    }
    # endif

























    main(argc,argv) char *argv[]; {
    exit(mainpp (argc,argv) );
    }

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Bart@bc@freeuk.com to comp.lang.c on Fri Jun 5 16:50:21 2026
    From Newsgroup: comp.lang.c

    On 05/06/2026 14:42, David Brown wrote:
    On 05/06/2026 13:39, Bart wrote:

    "a << (b + c)" has "more than needed" - that is objective.

    "a << (b + c)" does not have "too many" in an objective sense, because


    OK. Suppose "too many" /is/ subjective; what actual difference does it
    make to anything?

    I cannot speak for the intentions of others, but it has certainly been
    very frustrating trying to get you to understand the distinction between objective facts and subjective opinions,

    Why is that even important? I asked:

    Actual examples of too many parentheses?


    The reply was:

    The point of my comment is that either too many or too few is a
    subjective judgment, not an objective one.

    I didn't introduce this objective/subjective business. It seems now more
    like a ploy to devalue any arguments of mine, and also to evade
    answering; I'm still waiting for those examples from TR!

    These were his prior comments:

    Sadly the idea of writing in a way that is "most easily understood"
    has resulted in a race to the bottom, where writers are more and
    more encouraged to take the view that (some) readers are pretty
    much arbitrarily stupid, with the result that expressions become
    littered with scads of unnecessary parentheses that actually
    detract from ease of reading. Good writing is always a balance
    between too much and too little.

    So he obviously has his own tolerance level. I would also guess those 'writers' belong to that 0.1%.

    I would actually agree that parentheses can add clutter, but not that
    the answer is to not use them when they are optional.

    It C they are often added many of us (we are a lot more than 0.1%) need
    them to more easily parse code. That doesn't mean we are stupid.

    I suggested that minimising parentheses because the result is still 'unambiguous' is equivalent to doing away with indentation for the same reason.

    People didn't like that. Yet indentation and extra parentheses /are/
    both redundant.


    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Keith Thompson@Keith.S.Thompson+u@gmail.com to comp.lang.c on Fri Jun 5 11:01:24 2026
    From Newsgroup: comp.lang.c

    Tim Rentsch <tr.17687@z991.linuxsc.com> writes:
    Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:
    [...]
    The line `# 2 "hello.c"` is, according to the C standard, a
    "non-directive", which is a kind of directive. Executing a
    non-directive has undefined behavior,

    Since it is gcc that is generating the non-directives, for
    internal purposes, and gcc that is consuming them, it hardly
    seems worth worrying about whether their behavior is defined
    or not.

    I wasn't worried. I just mentioned in in passing.

    You quoted most of the article, but snipped relevant context in
    the middle of a sentence.
    --
    Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
    void Void(void) { Void(); } /* The recursive call of the void */
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Keith Thompson@Keith.S.Thompson+u@gmail.com to comp.lang.c on Fri Jun 5 11:09:34 2026
    From Newsgroup: comp.lang.c

    Bart <bc@freeuk.com> writes:
    On 05/06/2026 08:29, David Brown wrote:
    On 04/06/2026 21:29, Bart wrote:
    [...]
    TR:
    Sadly the idea of writing in a way that is "most easily understood"
    has resulted in a race to the bottom, where writers are more and
    more encouraged to take the view that (some) readers are pretty
    much arbitrarily stupid, with the result that expressions become
    littered with scads of unnecessary parentheses that actually
    detract from ease of reading. Good writing is always a balance
    between too much and too little.

    BC:
    Actual examples of too many parentheses?

    TR:
    The point of my comment is that either too many or too few is a
    subjective judgment, not an objective one.

    Here it is clear that 'too many' was just a paraphrase of
    'unnecessary'.

    No, it is clear that "too many" and "unnecessary" have two different
    meanings.

    I think you and I agree that the parentheses in `a << (b + c)`
    are *unnecessary* (in the specific sense that they do not affect
    the semantics of the expression), but they are not *too many*
    (in the sense that they are helpful to most human readers).

    The idea that "too many" and "unnecessary" mean the same thing
    is your own invention.

    [...]

    Tim Rentsch I'm sure will prefer the latter because 99.9% of C
    programmers are machines, according to him.

    Please give a reference for him saying that.-a (I'll save you the
    bother, he has not made any remarks remotely like this in
    c.l.c. since I have been here.)

    Find out what was the subject of the 99.9% (even if that was an exaggeration). Then we'll talk.

    Only Tim can clarify that point, and he's made it clear that he's
    not interested in doing so. Please don't complain to the rest of
    us about that.

    No, he didn't use the word 'machines'; I paraphrased to suggest
    supernormal people who know everything and never make mistakes.

    You're going to argue about this now?

    Bart, when you make ridiculous and/or false statements, people are going
    to argue with you. When you double down on such statements, people are
    going to continue to argue with you.

    Your use of the word "machines" was ridiculous and false.

    [...]
    --
    Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
    void Void(void) { Void(); } /* The recursive call of the void */
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Keith Thompson@Keith.S.Thompson+u@gmail.com to comp.lang.c on Fri Jun 5 11:24:52 2026
    From Newsgroup: comp.lang.c

    Tim Rentsch <tr.17687@z991.linuxsc.com> writes:
    Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:
    Tim Rentsch <tr.17687@z991.linuxsc.com> writes:
    Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:
    Note that in a context that requires a constant expression, overflow is >>>> a constraint violation. For example, a case label like:

    case (INT_MAX + 1) * 0:

    must be diagnosed at compile time.

    gcc disagrees with you.

    What makes you think so?

    [...]

    I'm skipping this and proceeding on to the original question.

    Why?

    You made a statement, "gcc disagrees with you". I demonstrated,
    in text that you snipped, that gcc does in fact agree with me.
    You were wrong. I don't know the basis of your error, so I asked.
    Or maybe I'm missing something, and you had a valid point that I
    didn't understand.

    You're not required to answer my question, which I think was
    an extremely reasonable one, but quoting it and then explicitly
    refusing to answer it is pointlessly rude.

    I'd like to know whether you still think you were right. If so,
    I'd like to see your explanation. If not, an admission that you
    made a mistake would be appreciated. But I expect neither from you.

    [SNIP]

    I see no basis for this belief. My conclusions are based on what
    the C standard actually says, rather than guesses about some
    unstated "intentions". I think you would do well to reach your
    conclusions based more on the actual text of the C standard, and
    less on your interpretation of what the text was "intended" to
    mean.

    The actual text of the standard implies that 42 is not an expression.
    I rely on the obvious intent to conclude that it is.
    --
    Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
    void Void(void) { Void(); } /* The recursive call of the void */
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From cross@cross@spitfire.i.gajendra.net (Dan Cross) to comp.lang.c on Sat Jun 6 03:22:03 2026
    From Newsgroup: comp.lang.c

    In article <86bjdpayv0.fsf@linuxsc.com>,
    Tim Rentsch <tr.17687@z991.linuxsc.com> wrote:
    Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:
    [snip]
    But taking a closer look at the standard, I'm not 100% sure that the
    language requires a diagnostic, though I think that's the intent.
    The relevant constraint is:

    Each constant expression shall evaluate to a constant that is
    in the range of representable values for its type.

    If I squint really hard, I can argue that the entire expression
    has to be a constant expression, but it doesn't say that its
    subexpressions are constant expressions -- and *if* INT_MAX +
    1 evaluates to INT_MIN in the current implementation, then
    (INT_MAX + 1) * 0 evaluates to 0 and therefore satisfies the
    constraint.

    My reasoning is as follows.

    To determine if the constraint is satisfied, the compiler must
    first evaluate the expression (INT_MAX + 1) * 0.

    To evaluate the expression (INT_MAX + 1) * 0, the compiler must
    first evaluate the sub-expression (INT_MAX + 1).

    Because the expression (INT_MAX + 1) overflows, the behavior is
    undefined, and the compiler is free to decide that the value of
    the sub-expression (INT_MAX + 1) is, let's say, 12.

    The compiler next evaluates the overall expression as 12*0, which
    is 0 (an int).

    This result of the overall expression satisfies the constraint,
    and so the compiler is not obliged to generate a diagnostic.

    The text of the standard explicitly carves this out; or, rather,
    it attempts to. If the result of an expression is not
    representable in the target type, _regardless of whether that's
    due to UB or not_, a diagnostic is required.

    But as it happens, I think I can see how your interpretation may
    be valid: if, as a result of UB, the expression evaluates to "0"
    (or 12 or something simiilar) that _is_ representable, then
    there _is no constraint violation_ and so no diagnostic is
    required.

    I do not believe that that is the intent. But it _is_
    conformant with the text of the standard.

    This is a problem with the C standard: it is insufficiently
    precise, as the semantics of the language are not formally
    defined.

    [snip]
    I see no basis for this belief. My conclusions are based on what
    the C standard actually says, rather than guesses about some
    unstated "intentions". I think you would do well to reach your
    conclusions based more on the actual text of the C standard, and
    less on your interpretation of what the text was "intended" to
    mean.

    The same could be said to you, as well. There exists a reading
    of the standard by which your `foo`-containing program is not
    strictly conforming . But that way lies madness; C is not a
    formally specified language. Given that as an objective fact,
    we must accept intent, consistency, and other "soft" aspects
    when considering its definition.

    That sort of sucks, but here we are.

    - Dan C.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From cross@cross@spitfire.i.gajendra.net (Dan Cross) to comp.lang.c on Sat Jun 6 03:44:26 2026
    From Newsgroup: comp.lang.c

    In article <10vu703$11s5q$1@dont-email.me>, Bart <bc@freeuk.com> wrote:
    On 05/06/2026 08:53, Tim Rentsch wrote:
    cross@spitfire.i.gajendra.net (Dan Cross) writes:

    In article <10vsrpo$men2$2@dont-email.me>, Bart <bc@freeuk.com> wrote:

    On 04/06/2026 22:06, Keith Thompson wrote:

    Bart <bc@freeuk.com> writes:

    [snip]
    Tim Rentsch I'm sure will prefer the latter because 99.9% of C
    programmers are machines, according to him.

    Tim didn't say or imply that.

    So what was his 99.9% all about? Nobody has a clue, except they are
    certain that what I think it is is wrong!

    Have you thought about, I don't know, maybe asking him?

    Asking him straight questions is usually futile. You can probably guess
    this from the response below.

    I agree that that response was both unhelpful and hypocritical.

    Notice he hasn't tried to enlighten anyone about that 99.9%.

    I think my explanation was actually pretty close. YMMV.

    That may just have been a throwaway line like when I say 'nobody likes
    X', but I would still dispute that, if it's about what I think it is,
    it's anything like a super-majority.

    The point still stands. You should know your audience:
    comp.lang.c is a forum that prizes a certain kind of semantic
    precision. Perhaps your intent when you say things of the form,
    "X has too many parentheses" is to be informal; it will
    certainly not be taken that way here. And you _do_ have a track
    record of being wrong enough that you are unlikely to be
    afforded the benefit of the doubt.

    At the risk of saying what may be obvious to everyone, Bart has
    shown that he has no interest in having a serious, constructive,
    useful, or productive conversation with anyone. His questions
    are all rhetorical; he hasn't asked me a straight question
    because he isn't really interested in what I would say. In
    short, Bart isn't looking for an answer, he's looking for an
    argument. My recommendation is just stop responding to him
    altogether. My response to him upthread was a sincere effort to
    provide a neutral and helpful answer to his question. Maybe my
    remarks were helpful to other people, and if they were that's
    good. Any further efforts to interact with Bart are not just a
    waste of time but actually counterproductive. What Bart needs is
    not help with understanding C but a good therapist. In any case
    I'm confident that whatever Bart's needs may be, no one responding
    to his postings here is in a position to provide them. Please
    consider these remarks before responding to him further.

    Generally speaking, AFAIK, none of the regular posters here are
    qualified mental health professionals; as such, we should all
    avoid from making armchair psychological diagnoses, the
    occasionally midly offcolor joke aside ("that's crazy!").

    Stick to C, Tim.

    - Dan C.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From cross@cross@spitfire.i.gajendra.net (Dan Cross) to comp.lang.c on Sat Jun 6 03:45:04 2026
    From Newsgroup: comp.lang.c

    In article <86jysdb1yr.fsf@linuxsc.com>,
    Tim Rentsch <tr.17687@z991.linuxsc.com> wrote:
    I didn't read Bart's posting. Unfortunately it seems
    true that any continued interaction with his comments
    is counterproductive.

    As is your response. I, for one, can conceieve of no purpose to
    it other than to goad him. Do better.

    - Dan C.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From cross@cross@spitfire.i.gajendra.net (Dan Cross) to comp.lang.c on Sat Jun 6 03:49:30 2026
    From Newsgroup: comp.lang.c

    In article <DHAUR.47540$0o1c.29921@fx08.iad>,
    Scott Lurndal <slp53@pacbell.net> wrote:
    cross@spitfire.i.gajendra.net (Dan Cross) writes:
    In article <1BoUR.3$lmCb.1@fx22.iad>, Scott Lurndal <slp53@pacbell.net> wrote:
    cross@spitfire.i.gajendra.net (Dan Cross) writes:
    [snip]
    <snip>
    Yeah, that's from `cc.c`, right?

    No, it's from cpp.c

    $ ls /work/reference/collegetapes/sltape/v6cc/
    c0.c c00.c c01.c c02.c c03.c c04.c c05.c c1.h
    c10.c c11.c c12.c c13.c c2.h c20.c c21.c cc.c cpp.c

    Oh interesting. I don't have a `cpp.c` in my v6 archive.

    I wonder what else I'm missing.

    [snip]

    Thanks! This is an artifact definitely worth preserving. As
    far as I know, it's not in any of the extant V6 archives. I'll
    shoot you an email, if that's ok.

    - Dan C.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Janis Papanagnou@janis_papanagnou+ng@hotmail.com to comp.lang.c on Sat Jun 6 07:39:20 2026
    From Newsgroup: comp.lang.c

    On 2026-06-06 05:44, Dan Cross wrote:
    In article <10vu703$11s5q$1@dont-email.me>, Bart <bc@freeuk.com> wrote:
    On 05/06/2026 08:53, Tim Rentsch wrote:
    [...]
    [...]
    [...]

    Generally speaking, AFAIK, none of the regular posters here are
    qualified mental health professionals; as such, we should all
    avoid from making armchair psychological diagnoses, the
    occasionally midly offcolor joke aside ("that's crazy!").

    Do we need to know about the particle physics mechanics of
    H -> He fusion or Einstein's E = m c^2 to understand that
    our sun is emitting energy, giving us light and warms us?

    Janis :-}

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Keith Thompson@Keith.S.Thompson+u@gmail.com to comp.lang.c on Fri Jun 5 23:56:52 2026
    From Newsgroup: comp.lang.c

    cross@spitfire.i.gajendra.net (Dan Cross) writes:
    [...]
    The text of the standard explicitly carves this out; or, rather,
    it attempts to. If the result of an expression is not
    representable in the target type, _regardless of whether that's
    due to UB or not_, a diagnostic is required.
    [...]

    How would an expression (appearing in a context that requires an
    integer constant expression) not "evaluate to a constant that is in
    the range of representable values for its type" other than by UB?
    I can't think of an example, but I'd be interested in seeing one.

    Note in particular that UINT_MAX+1U is well defined, not an overflow.
    --
    Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
    void Void(void) { Void(); } /* The recursive call of the void */
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From scott@scott@slp53.sl.home (Scott Lurndal) to comp.lang.c on Sat Jun 6 17:53:01 2026
    From Newsgroup: comp.lang.c

    cross@spitfire.i.gajendra.net (Dan Cross) writes:
    In article <DHAUR.47540$0o1c.29921@fx08.iad>,
    Scott Lurndal <slp53@pacbell.net> wrote:
    cross@spitfire.i.gajendra.net (Dan Cross) writes:
    In article <1BoUR.3$lmCb.1@fx22.iad>, Scott Lurndal <slp53@pacbell.net> wrote:
    cross@spitfire.i.gajendra.net (Dan Cross) writes:
    [snip]
    <snip>
    Yeah, that's from `cc.c`, right?

    No, it's from cpp.c

    $ ls /work/reference/collegetapes/sltape/v6cc/
    c0.c c00.c c01.c c02.c c03.c c04.c c05.c c1.h
    c10.c c11.c c12.c c13.c c2.h c20.c c21.c cc.c cpp.c

    Oh interesting. I don't have a `cpp.c` in my v6 archive.

    I wonder what else I'm missing.

    [snip]

    Thanks! This is an artifact definitely worth preserving. As
    far as I know, it's not in any of the extant V6 archives. I'll
    shoot you an email, if that's ok.

    A a version of cpp that was used with the portable C compiler (PCC)
    is here.

    It has a -C option to preserve comments in the processed output.

    https://github.com/IanHarvey/pcc/blob/master/cc/cpp/cpp.c
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From dave_thompson_2@dave_thompson_2@comcast.net to comp.lang.c on Sat Jun 6 19:02:11 2026
    From Newsgroup: comp.lang.c

    On Mon, 1 Jun 2026 09:52:08 +0200, David Brown
    <david.brown@hesbynett.no> wrote:

    On 31/05/2026 19:11, Bart wrote:
    ...
    Actual examples of too many parentheses?

    Any source code written in LISP :-)

    (And for too few parentheses, any source code in Forth.)

    FORTH uses parentheses for stack diagrams -- a semi-standard type of comment/documentation -- and of course good code (using my subjective definition of good :-) ) always has sufficient documentation :-)
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From cross@cross@spitfire.i.gajendra.net (Dan Cross) to comp.lang.c on Sun Jun 7 13:37:35 2026
    From Newsgroup: comp.lang.c

    In article <1100gbk$1lt8i$2@kst.eternal-september.org>,
    Keith Thompson <Keith.S.Thompson+u@gmail.com> wrote: >cross@spitfire.i.gajendra.net (Dan Cross) writes:
    [...]
    The text of the standard explicitly carves this out; or, rather,
    it attempts to. If the result of an expression is not
    representable in the target type, _regardless of whether that's
    due to UB or not_, a diagnostic is required.
    [...]

    How would an expression (appearing in a context that requires an
    integer constant expression) not "evaluate to a constant that is in
    the range of representable values for its type" other than by UB?

    It wouldn't. But because it's UB, it could evaluate to
    anything, including something that didn't violate the
    constraint.

    I can't think of an example, but I'd be interested in seeing one.

    In terms of a practical, working compiler? I doubt that one
    exists.

    Note in particular that UINT_MAX+1U is well defined, not an overflow.

    Yes.

    - Dan C.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Keith Thompson@Keith.S.Thompson+u@gmail.com to comp.lang.c on Sun Jun 7 15:09:43 2026
    From Newsgroup: comp.lang.c

    cross@spitfire.i.gajendra.net (Dan Cross) writes:
    In article <1100gbk$1lt8i$2@kst.eternal-september.org>,
    Keith Thompson <Keith.S.Thompson+u@gmail.com> wrote:
    cross@spitfire.i.gajendra.net (Dan Cross) writes:
    [...]
    The text of the standard explicitly carves this out; or, rather,
    it attempts to. If the result of an expression is not
    representable in the target type, _regardless of whether that's
    due to UB or not_, a diagnostic is required.
    [...]

    How would an expression (appearing in a context that requires an
    integer constant expression) not "evaluate to a constant that is in
    the range of representable values for its type" other than by UB?

    It wouldn't. But because it's UB, it could evaluate to
    anything, including something that didn't violate the
    constraint.

    I can't think of an example, but I'd be interested in seeing one.

    In terms of a practical, working compiler? I doubt that one
    exists.

    I actually meant in terms of the standard, not of any particular
    compiler.

    I can't think of an example, but maybe someone else can.

    [...]
    --
    Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
    void Void(void) { Void(); } /* The recursive call of the void */
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From cross@cross@spitfire.i.gajendra.net (Dan Cross) to comp.lang.c on Mon Jun 8 02:33:58 2026
    From Newsgroup: comp.lang.c

    In article <1104q77$2qkh5$1@kst.eternal-september.org>,
    Keith Thompson <Keith.S.Thompson+u@gmail.com> wrote: >cross@spitfire.i.gajendra.net (Dan Cross) writes:
    In article <1100gbk$1lt8i$2@kst.eternal-september.org>,
    Keith Thompson <Keith.S.Thompson+u@gmail.com> wrote: >>>cross@spitfire.i.gajendra.net (Dan Cross) writes:
    [...]
    The text of the standard explicitly carves this out; or, rather,
    it attempts to. If the result of an expression is not
    representable in the target type, _regardless of whether that's
    due to UB or not_, a diagnostic is required.
    [...]

    How would an expression (appearing in a context that requires an
    integer constant expression) not "evaluate to a constant that is in
    the range of representable values for its type" other than by UB?

    It wouldn't. But because it's UB, it could evaluate to
    anything, including something that didn't violate the
    constraint.

    I can't think of an example, but I'd be interested in seeing one.

    In terms of a practical, working compiler? I doubt that one
    exists.

    I actually meant in terms of the standard, not of any particular
    compiler.

    I can't think of an example, but maybe someone else can.

    [...]

    Oh. Well, I suppose something that relied on _IB_, like
    conversion from a large unsigned integer type to a smaller
    signed integer type that led to a trap, might fall into that
    category.

    - Dan C.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Tim Rentsch@tr.17687@z991.linuxsc.com to comp.lang.c on Mon Jun 8 00:16:43 2026
    From Newsgroup: comp.lang.c

    cross@spitfire.i.gajendra.net (Dan Cross) writes:

    In article <86bjdpayv0.fsf@linuxsc.com>,
    Tim Rentsch <tr.17687@z991.linuxsc.com> wrote:

    Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:

    [snip]
    But taking a closer look at the standard, I'm not 100% sure that the
    language requires a diagnostic, though I think that's the intent.
    The relevant constraint is:

    Each constant expression shall evaluate to a constant that is
    in the range of representable values for its type.

    If I squint really hard, I can argue that the entire expression
    has to be a constant expression, but it doesn't say that its
    subexpressions are constant expressions -- and *if* INT_MAX +
    1 evaluates to INT_MIN in the current implementation, then
    (INT_MAX + 1) * 0 evaluates to 0 and therefore satisfies the
    constraint.

    My reasoning is as follows.

    To determine if the constraint is satisfied, the compiler must
    first evaluate the expression (INT_MAX + 1) * 0.

    To evaluate the expression (INT_MAX + 1) * 0, the compiler must
    first evaluate the sub-expression (INT_MAX + 1).

    Because the expression (INT_MAX + 1) overflows, the behavior is
    undefined, and the compiler is free to decide that the value of
    the sub-expression (INT_MAX + 1) is, let's say, 12.

    The compiler next evaluates the overall expression as 12*0, which
    is 0 (an int).

    This result of the overall expression satisfies the constraint,
    and so the compiler is not obliged to generate a diagnostic.

    The text of the standard explicitly carves this out; or, rather,
    it attempts to. If the result of an expression is not
    representable in the target type, _regardless of whether that's
    due to UB or not_, a diagnostic is required.

    That's right. However, the key point here is that it is the
    implementation that determines (following the semantic rules given
    in the C standard) what the value is, and so whether the value is
    representable in the type of the expression. Because of the
    undefined behavior present in the expression in question, the
    implementation is free to choose a value that /is/ representable,
    and of the appropriate type, in which case no diagnostic is
    required.

    But as it happens, I think I can see how your interpretation may
    be valid: if, as a result of UB, the expression evaluates to "0"
    (or 12 or something simiilar) that _is_ representable, then
    there _is no constraint violation_ and so no diagnostic is
    required.

    Right. In fact the reasoning doesn't have to be so elaborate.
    Just by looking at the types of the operands, a compiler can
    determine the result is type int. Then, just by noticing the
    multiplication by 0, a compiler could decide that the result is
    zero, because the compiler is free to assume that there was no
    undefined behavior in the left-hand side expression. Whether the
    left-hand size expression has undefined behavior doesn't even have
    to be checked to decide that (INT_MAX+1)*0 is 0, and so it can
    satisfy the constraints of an integer constant expression.

    I do not believe that that is the intent. But it _is_
    conformant with the text of the standard.

    I think your intuition is leading you astray. The people who
    wrote the C standard have gone to great lengths to say (write)
    what they mean and mean what they say (write). I don't see any
    evidence to suggest that this property doesn't apply in the
    situation being discussed.

    This is a problem with the C standard: it is insufficiently
    precise, as the semantics of the language are not formally
    defined.

    On the contrary, the C standard is quite precise: when a program
    construct is encountered that the Standard identifies as having
    undefined behavior, the Standard IMPOSES NO REQUIREMENTS on what
    behavior may result. That rule may not be what someone wants, but
    there isn't any question about what is allowed, which is anything
    at all.

    [snip]
    I see no basis for this belief. My conclusions are based on what
    the C standard actually says, rather than guesses about some
    unstated "intentions". I think you would do well to reach your
    conclusions based more on the actual text of the C standard, and
    less on your interpretation of what the text was "intended" to
    mean.

    The same could be said to you, as well. There exists a reading
    of the standard by which your `foo`-containing program is not
    strictly conforming .

    The difference is my reading is based on what the C standard
    actually says, and not on any guesses about "intent" or whether
    the result "makes sense". When reading the C standard it's
    important to develop the habit of reading the text as neutrally as
    one can, and not inject any subconscious ideas about what it ought
    to be saying.

    But that way lies madness; C is not a
    formally specified language. Given that as an objective fact,
    we must accept intent, consistency, and other "soft" aspects
    when considering its definition.

    The C standard is not written in formal mathematical language, but
    it is written in formal English. Certainly there are places in
    the standard where what is said does a poor job of conveying what
    is expected. But the particular case of (INT_MAX+1)*0 is not one
    of them.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From cross@cross@spitfire.i.gajendra.net (Dan Cross) to comp.lang.c on Mon Jun 8 12:41:11 2026
    From Newsgroup: comp.lang.c

    In article <8633yxa4dg.fsf@linuxsc.com>,
    Tim Rentsch <tr.17687@z991.linuxsc.com> wrote:
    cross@spitfire.i.gajendra.net (Dan Cross) writes:
    [snip]
    But as it happens, I think I can see how your interpretation may
    be valid: if, as a result of UB, the expression evaluates to "0"
    (or 12 or something simiilar) that _is_ representable, then
    there _is no constraint violation_ and so no diagnostic is
    required.

    Right. In fact the reasoning doesn't have to be so elaborate.
    Just by looking at the types of the operands, a compiler can
    determine the result is type int. Then, just by noticing the
    multiplication by 0, a compiler could decide that the result is
    zero, because the compiler is free to assume that there was no
    undefined behavior in the left-hand side expression. Whether the
    left-hand size expression has undefined behavior doesn't even have
    to be checked to decide that (INT_MAX+1)*0 is 0, and so it can
    satisfy the constraints of an integer constant expression.

    I understand why you are saying this. The relevant part of the
    syntax is,

    multiplicative-expression:
    ...
    multiplicative-expression * cast-expression
    ...

    Since UB imposes no requirements of any kind, the translator is
    free to assume that the evaluation of the
    `multiplicative-expression` component is well-defined, and
    then multiplication by a `cast-expression` that evaluates to 0
    is just 0.

    But it is a good exercise to back that up by the letter of the
    standard. Recall that in this context, Keith was talking about
    `case` labels.

    The grammar given in the standard explicitly says that, in that
    position, the expression must be a `constant-expression` (sec
    6.8.2 ["Labeled statements"] para 1, "Syntax"). Constant
    expressions must be evaluated in accordance with the semantic
    rules of the abstract machine (sec 6.6 para 17), the rules for
    which are spelled out in sec 5.1.2.4, specifically para 1, which
    read, "The semantic descriptions in this document describe the
    behavior of an abstract machine in which issues of optimization
    are irrelevant" and para 4, which says that "all expressions
    are evaluated as specified by the semantics."

    Para (4) goes on to say, "an actual implementation is not
    required to evaluate part of an expression if it can deduce that
    its value is not used and that no needed side effects are
    produced (including any caused by calling a function or through
    volatile access to an object)." So a translator is free to
    replace, e.g., `(2 + 2)*0)` with 0.

    But that doesn't mean that the presence of UB in this context is
    insignificant; in fact, this entire interpretation rests on it.

    I do not believe that that is the intent. But it _is_
    conformant with the text of the standard.

    I think your intuition is leading you astray. The people who
    wrote the C standard have gone to great lengths to say (write)
    what they mean and mean what they say (write). I don't see any
    evidence to suggest that this property doesn't apply in the
    situation being discussed.

    This is not an arugment; it's an assertion, based on your own
    intuition and your feelings about the text of the standard and
    the level of precision you assume it takes.

    In this specific context, Keith raised a valid point: how can
    the constraint mentioned in sec 6.6 para 4 ever be violated
    _without_ UB? And since C imposes no requirement _at all_ with
    respect to how a translator assesses the behavior of evaluating
    a UB-bearing expression, then how can the diagnostic requirement
    for a constraint violation ever be fulfilled here?

    My example is this:

    constexpr int A = ~0U;

    The type of the rhs is `int` and the value is not representable
    in a signed int. As expected, this fails to compile, with a
    diagnostic about the constraint violation:

    ```
    term% cc -std=c23 -c constraint.c
    constraint.c:1:19: error: constexpr initializer evaluates to 4294967295 which is not exactly representable in type 'const int'
    1 | constexpr int A = ~0U;
    | ^
    1 error generated.
    term%
    ```

    Adding an `(int)` cast takes advantage of IB, but allows the
    program to compile:

    ```
    term% cat constraint.c
    constexpr int A = (int)~0U;
    term% clang -Werror -pedantic -std=c23 -c constraint.c
    term%
    ```

    This is a problem with the C standard: it is insufficiently
    precise, as the semantics of the language are not formally
    defined.

    On the contrary, the C standard is quite precise:

    Consider that your definition of "precise" may not be shared.
    This is an example of your own subjectivity.

    when a program
    construct is encountered that the Standard identifies as having
    undefined behavior, the Standard IMPOSES NO REQUIREMENTS on what
    behavior may result. That rule may not be what someone wants, but
    there isn't any question about what is allowed, which is anything
    at all.

    My statement, that you quoted and responded to, was not limited
    to undefined behavior. Rather, it was a general statement about
    the imprecision of the C standard.

    For whatever reason you have chosen to take that general
    statement, and respond to it by posting about one thing that is
    clearly defined in the standard, and that further, I believe
    every participant in this discussion agrees on. But clarity and
    precision on a single point does not mean that the entire
    standard, taken as a whole, is similarly precise and clear.

    In fact, what I have been arguing all along is exactly what you
    wrote above: the standard imposes _no requirements_ on the
    resultant behavior of a program when a translator encounters
    a program construct (for example, something like `INT_MAX + 1`,
    whether immediately multiplied by zero or not) in the course of
    translating that program. The C standard does _not_ explicitly
    say otherwise.

    Unfortunately, the C standard is simply not a precise, formal
    document. This is well-known, and it's hardly C's fault: indeed
    most of the applications of formalized descriptions of PL
    semantics to practical programming languages postdates C's
    invention; Dana Scott didn't introduce the term, "operational
    semantics" until 1970, and it didn't start to make a serious
    impact on languages until later.

    That you would limit that statement to UB only betrays a lack of
    understanding of what you responded to. Whether that is my
    fault or yours, I don't know.

    [Note: I feel obliged to say that this is not the fault of the C
    committee, Dennis Ritchie, Ken Thompson, Brian Kernighan, PJ
    Plauger, Jean-Heyd Meneide, or anyone else; rather, it is an
    unfortunate consequence of history, and one that cannot
    reasonably be corrected.]

    [snip]
    I see no basis for this belief. My conclusions are based on what
    the C standard actually says, rather than guesses about some
    unstated "intentions". I think you would do well to reach your
    conclusions based more on the actual text of the C standard, and
    less on your interpretation of what the text was "intended" to
    mean.

    The same could be said to you, as well. There exists a reading
    of the standard by which your `foo`-containing program is not
    strictly conforming .

    The difference is my reading is based on what the C standard
    actually says, and not on any guesses about "intent" or whether
    the result "makes sense". When reading the C standard it's
    important to develop the habit of reading the text as neutrally as
    one can, and not inject any subconscious ideas about what it ought
    to be saying.

    Your reading of the standard is subjective and, as far as I can
    tell, based on your own intuitions and presumptions of intent.
    Indeed we see direct evidence of this in the message I quoted
    above, where you ascribe a certain type of formality to that
    document, that is not warranted. Notice that your response to
    my post about _an_ intepretation of that document is not to
    point out how the text invalidates that reading, but rather, an
    admonission on how to read the standard.

    You would do well to take a moment and examine your own
    preconceptions in how you read that document and approach the C
    langauge.

    But that way lies madness; C is not a
    formally specified language. Given that as an objective fact,
    we must accept intent, consistency, and other "soft" aspects
    when considering its definition.

    The C standard is not written in formal mathematical language, but
    it is written in formal English.

    Correct.

    The C standard is written in the formal _register_; that is a
    matter of voice, but is dramatically different than a formal
    document with rigorously defined semantics. It is full of terms
    of art, and things that are imprecisely and informally specified
    in prose. The C standard strives, but sadlyfalls short in many
    places.

    Plenty of documents are written in a formal register and are
    still ambiguous and imprecise. That is one of the problems with
    trying to define something like a programming language precisely
    in prose.

    Gogol wrote a rather famous story about a non-existent officer
    who was accidentally manifested by a missing comma. He didn't
    exist, yet rose to become one of the Czar's favorites, as he
    never made a mistake (since he did not exist).

    Perhaps you will meditate on the implied analogy.

    Certainly there are places in
    the standard where what is said does a poor job of conveying what
    is expected. But the particular case of (INT_MAX+1)*0 is not one
    of them.

    This is a strawman. You are correct that the standard is clear
    as to the meaning, or more precisely lack thereof, of
    `(INT_MAX + 1)*0`, when considered as an isolated expression.
    What is much less clear are the implications of that when
    translated.

    - Dan C.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Tim Rentsch@tr.17687@z991.linuxsc.com to comp.lang.c on Mon Jun 8 08:35:42 2026
    From Newsgroup: comp.lang.c

    Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:

    Tim Rentsch <tr.17687@z991.linuxsc.com> writes:

    Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:

    Tim Rentsch <tr.17687@z991.linuxsc.com> writes:

    Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:

    Note that in a context that requires a constant expression, overflow is >>>>> a constraint violation. For example, a case label like:

    case (INT_MAX + 1) * 0:

    must be diagnosed at compile time.

    gcc disagrees with you.

    What makes you think so?

    [...]

    I'm skipping this and proceeding on to the original question.

    Why?

    gcc is not authoritative. I didn't want to get into an argument
    about whether gcc is conforming, or which version of gcc was used,
    or any similar distractions. The C standard /is/ authoritative,
    and I thought it would save time to cut to the chase.

    You made a statement, "gcc disagrees with you". I demonstrated,
    in text that you snipped, that gcc does in fact agree with me.

    No, you didn't.

    You were wrong.

    No, I wasn't. Your testing was faulty.

    I don't know the basis of your error, so I asked.
    Or maybe I'm missing something, and you had a valid point that I
    didn't understand.

    I'm offended that you think I have an obligation to remedy your
    habit of lazy thinking, especially when as here the answer was
    staring you right in the face, and you simply ignored it.

    You're not required to answer my question, which I think was
    an extremely reasonable one, but quoting it and then explicitly
    refusing to answer it is pointlessly rude.

    I wasn't refusing to answer. What I was doing was trying to
    answer the original question, and answer it in a way that wouldn't
    get lost in pointless bickering. Silly me.

    I'd like to know whether you still think you were right. If so,
    I'd like to see your explanation. If not, an admission that you
    made a mistake would be appreciated. But I expect neither from you.

    I'd like to know why you ignored my explanation, based directly on
    text from the C standard, about why an implementation is allowed to
    process the code in question, without giving a diagnostic, and
    still be conforming. An explanation that Dan Cross agreed with,
    even if he may not like the consequences.

    In investigating this question, I have run compilations using
    multiple versions of gcc, on two different platforms. I have looked
    carefully through the gcc man page. I have also run compilations
    using multiple versions of clang, on two different platforms. After
    doing all that, I ran compilations using godbolt, so I could check
    the latest, or maybe almost latest, versions of gcc and clang. All
    the different versions of gcc and clang that I have tried support my
    hypothesis that gcc (and now also clang) interpret the C standard so
    as to conclude that conforming to the C standard need not require a
    diagnostic for situations like the code under discussion..

    I'd like to ask you to do two things. First, read through the
    reasoning given in my previous post, try to assess whether that
    reasoning is sound, and post the results of yours contemplations.
    Second, look again at the question of whether gcc (and also clang,
    if you're up to it) support the hypothesis that a conforming
    implementation need not give a diagnostic for code like that under
    discussion. See if you can find a way of framing the question that
    supports my statement, rather than simply looking for one that
    supports your preconceived ideas. Post the results of your
    investigations, both what other experiments you tried, and what your
    assessment is of the results you got.

    Do these two things and I will endeavor to explain my views on the
    questions you have raised here, if such explanations are still
    needed after your further examinations and comments.

    [SNIP]

    I see no basis for this belief. My conclusions are based on what
    the C standard actually says, rather than guesses about some
    unstated "intentions". I think you would do well to reach your
    conclusions based more on the actual text of the C standard, and
    less on your interpretation of what the text was "intended" to
    mean.

    The actual text of the standard implies that 42 is not an expression.
    I rely on the obvious intent to conclude that it is.

    Now it is you who is changing the subject. Besides not being on
    point to the question being considered, it's a silly argument, and I
    would hope you are smart enough to realize that. However, if you do
    what I have asked in the previous paragraph, I can try to explain
    why I think your views on this unrelated matter are wrongheaded.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From cross@cross@spitfire.i.gajendra.net (Dan Cross) to comp.lang.c on Mon Jun 8 17:33:42 2026
    From Newsgroup: comp.lang.c

    In article <86y0gp82pd.fsf@linuxsc.com>,
    Tim Rentsch <tr.17687@z991.linuxsc.com> wrote:
    Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:

    Tim Rentsch <tr.17687@z991.linuxsc.com> writes:

    Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:

    Tim Rentsch <tr.17687@z991.linuxsc.com> writes:

    Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:

    Note that in a context that requires a constant expression, overflow is >>>>>> a constraint violation. For example, a case label like:

    case (INT_MAX + 1) * 0:

    must be diagnosed at compile time.

    gcc disagrees with you.

    What makes you think so?

    [...]

    I'm skipping this and proceeding on to the original question.

    Why?

    gcc is not authoritative.

    You, Tim, wrote the words, "gcc disagrees with you."

    If you didn't want to bring GCC into it, because it is not
    authoritative (which is true), then why did you mention it in
    the first place?

    I didn't want to get into an argument
    about whether gcc is conforming, or which version of gcc was used,
    or any similar distractions.

    You opened that door and walked through it.

    The C standard /is/ authoritative,
    and I thought it would save time to cut to the chase.

    Then you should have done that from the start, and not mentioned
    GCC.

    [snip]
    I'd like to know whether you still think you were right. If so,
    I'd like to see your explanation. If not, an admission that you
    made a mistake would be appreciated. But I expect neither from you.

    I'd like to know why you ignored my explanation, based directly on
    text from the C standard, about why an implementation is allowed to
    process the code in question, without giving a diagnostic, and
    still be conforming. An explanation that Dan Cross agreed with,
    even if he may not like the consequences.

    I am mystified as to why you are bringing my name into this, and
    why you think "I may not like the consequences", or even what
    that means. In any event, you are evidently laboring under some
    assumption about what I think about this matter that is probably
    incorrect.

    Because I am not you, I cannot know this for a fact, let alone
    why it may be. Regardless, I suggest you don't do that, or at a
    minimum seek clarity from the referent of your assumptions,
    before making claims about they may think.

    In investigating this question, I have run compilations using
    multiple versions of gcc, on two different platforms. I have looked >carefully through the gcc man page. I have also run compilations
    using multiple versions of clang, on two different platforms. After
    doing all that, I ran compilations using godbolt, so I could check
    the latest, or maybe almost latest, versions of gcc and clang. All
    the different versions of gcc and clang that I have tried support my >hypothesis that gcc (and now also clang) interpret the C standard so
    as to conclude that conforming to the C standard need not require a >diagnostic for situations like the code under discussion..

    It appears that you are appealing to a certain kind of semantic
    precision, that is itself based on a number of assumptions that
    are unstated, but that are implicit in your writing. Further,
    you give every indication of believing that a reader should
    simply intuitively know.

    In fact, both GCC and clang (the versions I tried on the
    platforms I tried on) emit a diagnostic for the code under
    consideration. Your assertion appears to be that that is
    unrelated to the constraint in section 6.6 para 4, which seems
    accurate.

    But you did not say that: instead, you just made a vague
    statement that "gcc disagrees with you." That's not useful, and
    no one can reasonably know what you meant unless you elaborated
    on it.

    When it was pointed out to you that in fact GCC generates a
    diagnostic, you had an opportunity to clarify that it was not in
    response to the aforementioned constraint violation. You chose
    not to do so, and instead of arrogantly accuse others of
    laziness and a lack of willingness to understand.

    Insisting that your readers adhere to some arbitrary level of
    semantic precision you seem to fancy yourself expressing is not
    actually a sign of true expertise. Real expertise is most
    readily demonstrated through effective communication.

    I'd like to ask you to do two things. First, read through the
    reasoning given in my previous post, try to assess whether that
    reasoning is sound, and post the results of yours contemplations.

    Second, look again at the question of whether gcc (and also clang,
    if you're up to it) support the hypothesis that a conforming
    implementation need not give a diagnostic for code like that under >discussion. See if you can find a way of framing the question that
    supports my statement, rather than simply looking for one that
    supports your preconceived ideas. Post the results of your
    investigations, both what other experiments you tried, and what your >assessment is of the results you got.

    Do these two things and I will endeavor to explain my views on the
    questions you have raised here, if such explanations are still
    needed after your further examinations and comments.

    It is rather cavalier to make imperative statements to others
    regarding how they must spend their time.

    [SNIP]

    I see no basis for this belief. My conclusions are based on what
    the C standard actually says, rather than guesses about some
    unstated "intentions". I think you would do well to reach your
    conclusions based more on the actual text of the C standard, and
    less on your interpretation of what the text was "intended" to
    mean.

    The actual text of the standard implies that 42 is not an expression.
    I rely on the obvious intent to conclude that it is.

    Now it is you who is changing the subject. Besides not being on
    point to the question being considered, it's a silly argument, and I
    would hope you are smart enough to realize that. However, if you do
    what I have asked in the previous paragraph, I can try to explain
    why I think your views on this unrelated matter are wrongheaded.

    Is it a silly argument?

    Perhaps Keith has some reason for suggesting that such an
    interpretation is be valid. I'm not aware of what that might
    be, but I suspect you are not, either. But without even knowing
    what the argument is, how would you know?

    You are the one admonishing others to look at the letter of the
    standard ("My conclusions are based on what the C standard
    actually says..."), yet here you dismiss as "a silly argument",
    a thing brought up by someone who has demonstrated that they
    generally know what they're talking about, and you have done so
    without even bothering to ask what they might be refering to.

    In fact, I think this fits a pattern of behavior I observe from
    you fairly consistently. You decide on an interpretation,
    declare it correct, and appear to scoff at anyone else who does
    not immediately share that interpretation as being "lazy" or
    worse.

    Ironically, you yourself do not do well when you are shown to be
    wrong about something; cf your bizarre statement about Rust not
    being strongly typed. This does not do well for your
    credibility; everyone makes mistakes now and again, and you are
    no different, but your seeming inability to admit to it when it
    is obvious decreases faith in your interpretations when they are
    not obvious.

    You would do well to express more humility, and consider how
    others might perceive you based on the way you talk to them.

    - Dan C.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From cross@cross@spitfire.i.gajendra.net (Dan Cross) to comp.lang.c on Mon Jun 8 17:37:52 2026
    From Newsgroup: comp.lang.c

    In article <1106d97$huo$1@reader1.panix.com>,
    Dan Cross <cross@spitfire.i.gajendra.net> wrote:
    My example is this:

    constexpr int A = ~0U;

    The type of the rhs is `int` and the value is not representable

    *sigh* "The type of the rhs is `unsigned int` and the value is
    not representable in a `signed int`.

    Perhaps,

    constexpr int A = (unsigned int)INT_MAX + 1;

    ...is an even better example.

    - Dan C.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Keith Thompson@Keith.S.Thompson+u@gmail.com to comp.lang.c on Mon Jun 8 13:40:56 2026
    From Newsgroup: comp.lang.c

    Tim Rentsch <tr.17687@z991.linuxsc.com> writes:
    Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:
    Tim Rentsch <tr.17687@z991.linuxsc.com> writes:
    Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:
    Tim Rentsch <tr.17687@z991.linuxsc.com> writes:
    Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:
    Note that in a context that requires a constant expression, overflow is >>>>>> a constraint violation. For example, a case label like:

    case (INT_MAX + 1) * 0:

    must be diagnosed at compile time.

    gcc disagrees with you.

    What makes you think so?

    [...]

    I'm skipping this and proceeding on to the original question.

    What question? I made a statement.

    Why?

    gcc is not authoritative. I didn't want to get into an argument
    about whether gcc is conforming, or which version of gcc was used,
    or any similar distractions. The C standard /is/ authoritative,
    and I thought it would save time to cut to the chase.

    I never said gcc is authoritative. *You* brought gcc into the
    discussion.

    It is a fact that gcc issues a diagnostic for that case label.
    It is a fact that it's a non-fatal warning with "-pedantic" and a
    fatal error with "-pedantic-errors", which implies, as I understand
    it, that the authors of gcc believe that the diagnostic is required
    by the standard.

    You made a statement, "gcc disagrees with you". I demonstrated,
    in text that you snipped, that gcc does in fact agree with me.

    No, you didn't.

    Yes, I did.

    You were wrong.

    No, I wasn't. Your testing was faulty.

    Yes, you were. My testing was not faulty.

    What exactly did you mean by "gcc disagrees with you"? I
    think it's sufficiently obvious that gcc does not have opinions,
    so you presumably were speaking figuratively in some sense.
    Do you not see the same diagnostic I saw?

    I don't know the basis of your error, so I asked.
    Or maybe I'm missing something, and you had a valid point that I
    didn't understand.

    I'm offended that you think I have an obligation to remedy your
    habit of lazy thinking, especially when as here the answer was
    staring you right in the face, and you simply ignored it.

    OK. I'm offended by your superior attitude. I'm offended by your
    refusal to consider that you might have made a mistake. I'm offended
    by your refusal to explain what you meant by an unclear statement
    after I repeatedly ask you to do so. I'm offended by your apparent
    assumption that if the rest of us just *think really hard*, we'll
    inevitably agree with you.

    You're not required to answer my question, which I think was
    an extremely reasonable one, but quoting it and then explicitly
    refusing to answer it is pointlessly rude.

    I wasn't refusing to answer. What I was doing was trying to
    answer the original question, and answer it in a way that wouldn't
    get lost in pointless bickering. Silly me.

    I'm assuming that by "the original question", you're referring to my *statement* that a diagnostic is required for the above case label.
    If you have some other "original question" in mind, please specify
    it. Please do not insult me by assuming that I'll know exactly
    what you mean if I just reread what you wrote and think hard enough.

    If you were trying to answer the "original question", you failed.
    You expressed your supposed disagrement by asserting, without
    further explanation, that gcc disagrees with me -- when, in fact,
    it does not, and when gcc's behavior is not directly relevant to
    the original statement anyway (since, as you correctly point out,
    gcc is not authoritative).

    I'd like to know whether you still think you were right. If so,
    I'd like to see your explanation. If not, an admission that you
    made a mistake would be appreciated. But I expect neither from you.

    I'd like to know why you ignored my explanation, based directly on
    text from the C standard, about why an implementation is allowed to
    process the code in question, without giving a diagnostic, and
    still be conforming. An explanation that Dan Cross agreed with,
    even if he may not like the consequences.

    That explanation is not relevant to your claim that gcc disagrees
    with me, which is what I asked you about.

    In investigating this question, I have run compilations using
    multiple versions of gcc, on two different platforms. I have looked carefully through the gcc man page. I have also run compilations
    using multiple versions of clang, on two different platforms. After
    doing all that, I ran compilations using godbolt, so I could check
    the latest, or maybe almost latest, versions of gcc and clang. All
    the different versions of gcc and clang that I have tried support my hypothesis that gcc (and now also clang) interpret the C standard so
    as to conclude that conforming to the C standard need not require a diagnostic for situations like the code under discussion..

    You've told us what you concluded from your compilations using godbolt.
    You haven't told us what those compilations actually told you.

    On the off chance that you're willing to answer a straightforward
    question:

    Here's one result I got on my system:

    $ gcc16 --version | head -n 1
    gcc16 (GCC) 16.1.0
    $ cat c.c
    #include <limits.h>
    int main(void) {
    switch(0) {
    case (INT_MAX + 1) * 0:
    break;
    }
    }
    $ gcc16 -std=c23 -pedantic-errors -c c.c
    c.c: In function rCymainrCO:
    c.c:4:23: warning: integer overflow in expression of type rCyintrCO results in rCy-2147483648rCO [-Woverflow]
    4 | case (INT_MAX + 1) * 0:
    | ^
    c.c:4:9: error: overflow in constant expression [-Woverflow]
    4 | case (INT_MAX + 1) * 0:
    | ^~~~
    $

    gcc emitted a fatal error message on that case label. Have you
    seen any version of gcc, either on your system or on godbolt,
    *not* issue a fatal error message when invoked on that source with
    "-std=cNN -pedantic-errors" (NN=23, or any valid value you like)?
    If so, have you seen it not at least issue a warning?

    If not, what is the basis for your claim that gcc disagrees with me?

    It's conceivable that what you meant is that gcc happens to issue
    a diagnostic, but is not required to. If so, then (a) that's
    sufficiently subtle that any reasonable person would have explained
    that point, and (b) given that gcc produces a diagnostic, I see no
    basis to assume that gcc "thinks" it's not required to do so.

    I'd like to ask you to do two things. First, read through the
    reasoning given in my previous post, try to assess whether that
    reasoning is sound, and post the results of yours contemplations.
    Second, look again at the question of whether gcc (and also clang,
    if you're up to it) support the hypothesis that a conforming
    implementation need not give a diagnostic for code like that under discussion. See if you can find a way of framing the question that
    supports my statement, rather than simply looking for one that
    supports your preconceived ideas. Post the results of your
    investigations, both what other experiments you tried, and what your assessment is of the results you got.

    You made a very simple claim, that gcc disagrees with me. I'm asking
    you about *that statement*. Do you still assert that gcc disagrees
    with me? (That is not a question about the C standard.)

    Do these two things and I will endeavor to explain my views on the
    questions you have raised here, if such explanations are still
    needed after your further examinations and comments.

    [SNIP]

    I see no basis for this belief. My conclusions are based on what
    the C standard actually says, rather than guesses about some
    unstated "intentions". I think you would do well to reach your
    conclusions based more on the actual text of the C standard, and
    less on your interpretation of what the text was "intended" to
    mean.

    The actual text of the standard implies that 42 is not an expression.
    I rely on the obvious intent to conclude that it is.

    Now it is you who is changing the subject. Besides not being on
    point to the question being considered, it's a silly argument, and I
    would hope you are smart enough to realize that. However, if you do
    what I have asked in the previous paragraph, I can try to explain
    why I think your views on this unrelated matter are wrongheaded.

    Please be less condescending.

    Leaving gcc aside, my original statement was that a case label like:

    case (INT_MAX + 1) * 0:

    is a constraint violation (and therefore that it requires a diagnostic).
    It's possible that I'm mistaken on that point. The constraint I claim
    it violates is that "Each constant expression shall evaluate to a
    constant that is in the range of representable values for its type."

    We could have discussed that much more briefly if you hadn't dragged
    gcc into it.

    I acknowledge that it can also be reasonably argued that the
    expression as a whole *can*, for a particular implementation, yield
    a result of 0, and therefore that a diagnostic is not required *for
    such an implementation*.

    The committee response to C90 DR #031 contradicts that argument:

    case (INT_MAX*4)/4: is a constraint violation.
    When subclause 6.4 says on page 55, lines 11-12:

    Each constant expression shall evaluate to a constant that is in the
    range of representable values for its type.

    the Committee's judgement of the intent is that the
    ``representable'' requirement applies to each subexpression of
    a constant expression, as shown in the third example. A constant
    expression is meant as defined by the syntax rules.

    My judgement of the intent agrees with the Committee's, and, as
    far as I can tell, with gcc's.

    (I do think that the wording in the standard could and should be
    improved.)
    --
    Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
    void Void(void) { Void(); } /* The recursive call of the void */
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Tim Rentsch@tr.17687@z991.linuxsc.com to comp.lang.c on Tue Jun 9 00:54:08 2026
    From Newsgroup: comp.lang.c

    cross@spitfire.i.gajendra.net (Dan Cross) writes:

    In article <86y0gp82pd.fsf@linuxsc.com>,
    Tim Rentsch <tr.17687@z991.linuxsc.com> wrote:

    [...]

    I'd like to know why you ignored my explanation, based directly on
    text from the C standard, about why an implementation is allowed to
    process the code in question, without giving a diagnostic, and
    still be conforming. An explanation that Dan Cross agreed with,
    even if he may not like the consequences.

    I am mystified as to why you are bringing my name into this, and
    why you think "I may not like the consequences", or even what
    that means. In any event, you are evidently laboring under some
    assumption about what I think about this matter that is probably
    incorrect.

    In a response to another posting of mine, you wrote this:

    But as it happens, I think I can see how your interpretation may
    be valid: if, as a result of UB, the expression evaluates to "0"
    (or 12 or something simiilar) that _is_ representable, then
    there _is no constraint violation_ and so no diagnostic is
    required.

    I do not believe that that is the intent. But it _is_
    conformant with the text of the standard.

    I based my statement that begins "An explanation that Dan Cross
    agreed with, ..." on those two paragraphs.
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From cross@cross@spitfire.i.gajendra.net (Dan Cross) to comp.lang.c on Tue Jun 9 10:08:09 2026
    From Newsgroup: comp.lang.c

    In article <86pl2087z3.fsf@linuxsc.com>,
    Tim Rentsch <tr.17687@z991.linuxsc.com> wrote:
    cross@spitfire.i.gajendra.net (Dan Cross) writes:

    In article <86y0gp82pd.fsf@linuxsc.com>,
    Tim Rentsch <tr.17687@z991.linuxsc.com> wrote:

    [...]

    I'd like to know why you ignored my explanation, based directly on
    text from the C standard, about why an implementation is allowed to
    process the code in question, without giving a diagnostic, and
    still be conforming. An explanation that Dan Cross agreed with,
    even if he may not like the consequences.

    I am mystified as to why you are bringing my name into this, and
    why you think "I may not like the consequences", or even what
    that means. In any event, you are evidently laboring under some
    assumption about what I think about this matter that is probably
    incorrect.

    In a response to another posting of mine, you wrote this:

    But as it happens, I think I can see how your interpretation may
    be valid: if, as a result of UB, the expression evaluates to "0"
    (or 12 or something simiilar) that _is_ representable, then
    there _is no constraint violation_ and so no diagnostic is
    required.

    I do not believe that that is the intent. But it _is_
    conformant with the text of the standard.

    I based my statement that begins "An explanation that Dan Cross
    agreed with, ..." on those two paragraphs.

    Nothing in those two paragraphs asserts that I am unhappy with
    the consequences; I neither like nor dislike the "consequences."
    I simply don't think that was the intent of people who wrote the
    standard.

    Before asserting a subjective interpretation of what someone
    else feels about a thing, you should seek to clarify if what you
    intent to say is accurate. Better yet, just don't do it. And
    of course, what I think about the matter is irrelevant to what
    you wrote to Keith, which I found sufficiently distasteful that
    I rather wish you hadn't mentioned my name in it at all.

    The rest of my earlier response stands.

    - Dan C.

    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Janis Papanagnou@janis_papanagnou+ng@hotmail.com to comp.lang.c on Tue Jun 9 16:05:03 2026
    From Newsgroup: comp.lang.c

    On 2026-06-08 14:41, Dan Cross wrote:
    [...]

    Unfortunately, the C standard is simply not a precise, formal
    document. This is well-known, and it's hardly C's fault: indeed
    most of the applications of formalized descriptions of PL
    semantics to practical programming languages postdates C's
    invention; Dana Scott didn't introduce the term, "operational
    semantics" until 1970, and it didn't start to make a serious
    impact on languages until later.

    Disclaimer: I haven't read Dana Scott's source that you refer to.
    Myself I've heard that term at university during the early 1980's.
    In 1970 my "knowledge" about computers was on Star-Trek level only.

    I just want to point out Algol 68's formal specification (pre-1970).

    And provide this quote on "Operational Semantic" (from Wikipedia):
    "The concept of operational semantics was used for the first time
    in defining the semantics of Algol 68."

    But Algol 68 was certainly outstanding here, concerning its formal specification, compared to most other languages back these days.

    Janis

    [...]

    --- Synchronet 3.22a-Linux NewsLink 1.2