• how to make a macro work as a single line if stmt without braces

    From Mark Summerfield@21:1/5 to All on Sat Sep 21 07:35:49 2024
    I have this macro:

    #define WARN(...) \
    do { \
    fprintf(stderr, "%s#%d: ", __FILE__, __LINE__); \
    fprintf(stderr, __VA_ARGS__); \
    } while (0);

    which I use like this:

    total++;
    if (failed) {
    WARN("failed because...");
    } else
    ok++;

    I would prefer to be able to write this instead:

    total++;
    if (failed)
    WARN("failed because...");
    else
    ok++;

    but doing so results in a compiler error:

    error: 'else' without a previous 'if'

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lawrence D'Oliveiro@21:1/5 to Mark Summerfield on Sat Sep 21 08:10:51 2024
    On Sat, 21 Sep 2024 07:35:49 +0000, Mark Summerfield wrote:

    I would prefer to be able to write this instead:

    total++;
    if (failed)
    WARN("failed because...");
    else
    ok++;

    I wouldn’t, if I were you.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Bart@21:1/5 to Mark Summerfield on Sat Sep 21 10:13:00 2024
    On 21/09/2024 08:35, Mark Summerfield wrote:
    I have this macro:

    #define WARN(...) \
    do { \
    fprintf(stderr, "%s#%d: ", __FILE__, __LINE__); \
    fprintf(stderr, __VA_ARGS__); \
    } while (0);

    which I use like this:

    total++;
    if (failed) {
    WARN("failed because...");
    } else
    ok++;

    I would prefer to be able to write this instead:

    total++;
    if (failed)
    WARN("failed because...");
    else
    ok++;

    but doing so results in a compiler error:

    error: 'else' without a previous 'if'

    Remove the semicolon at the end of the macro.

    As it is, it compiles to:

    if (failed) do {...} while 0;; else ok++:

    There are two semicolons together, the second terminates the whole if statement, leaving an open 'else'.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From David Brown@21:1/5 to Mark Summerfield on Sat Sep 21 10:47:10 2024
    On 21/09/2024 09:35, Mark Summerfield wrote:
    I have this macro:

    #define WARN(...) \
    do { \
    fprintf(stderr, "%s#%d: ", __FILE__, __LINE__); \
    fprintf(stderr, __VA_ARGS__); \
    } while (0);

    which I use like this:

    total++;
    if (failed) {
    WARN("failed because...");
    } else
    ok++;

    I would prefer to be able to write this instead:

    total++;
    if (failed)
    WARN("failed because...");
    else
    ok++;

    but doing so results in a compiler error:

    error: 'else' without a previous 'if'

    You should get in the habit of being consistent with braces, and being
    generous with them. Your future self with thank you.

    if (failed) {
    WARN("failed because...");
    } else {
    ok++;
    }


    The rule here is that you the /only/ time you allow yourself to omit the
    braces is if you have a very simple "if" that has no "else", is small
    enough to fit entirely on a single line, and the statement could not
    possibly be misinterpreted, use a macro, or have any other non-obvious behaviour.

    Thus :

    if (failed) return -1; // Early exit

    or

    if (!failed) ok++;

    Otherwise, put in all the braces.

    This also keeps your indentation consistent - open braces are only at
    the end of a line, and the next line starts an indented block. Close
    braces are only ever the first non-indent character in a line, and you un-indent on the close brace.

    (It's common to put the opening brace of a function at the start of its
    own line, and braces for struct or array initialisation can be freer.)

    do, while and for loops always use braces.



    There are a few other variant styles that are also consistent and clear,
    but usually they end up unnecessarily spread out. (Opinions will vary
    about that.) But getting good habits here from early one will make your
    code much clearer, greatly reduce the risk of blocking errors, and be a significant boon for code maintenance and the use of version control
    systems.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Ike Naar@21:1/5 to Mark Summerfield on Sat Sep 21 09:15:40 2024
    On 2024-09-21, Mark Summerfield <[email protected]> wrote:
    I have this macro:

    #define WARN(...) \
    do { \
    fprintf(stderr, "%s#%d: ", __FILE__, __LINE__); \
    fprintf(stderr, __VA_ARGS__); \
    } while (0);

    [...]

    I would prefer to be able to write this instead:

    total++;
    if (failed)
    WARN("failed because...");
    else
    ok++;

    but doing so results in a compiler error:

    error: 'else' without a previous 'if'

    After expansion of the WARN macro there are two semicolons before the 'else'. The first semicolon is from the

    } while (0);

    line, the second is from the


    WARN("failed because...");

    line.
    Removing the semicolon from one of these two lines fixes the compiler error.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mark Summerfield@21:1/5 to All on Sat Sep 21 09:53:29 2024
    Thank you Bart & Ike: I removed the ; and now the macro works great.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Tim Rentsch@21:1/5 to Mark Summerfield on Sat Sep 21 06:07:15 2024
    Mark Summerfield <[email protected]> writes:

    I have this macro:

    #define WARN(...) \
    do { \
    fprintf(stderr, "%s#%d: ", __FILE__, __LINE__); \
    fprintf(stderr, __VA_ARGS__); \
    } while (0);

    which I use like this:

    total++;
    if (failed) {
    WARN("failed because...");
    } else
    ok++;

    I would prefer to be able to write this instead:

    total++;
    if (failed)
    WARN("failed because...");
    else
    ok++;

    but doing so results in a compiler error:

    error: 'else' without a previous 'if'

    You can define WARN() this way

    #define WARN(...) ( \
    fprintf(stderr, "%s#%d: ", __FILE__, __LINE__), \
    fprintf(stderr, __VA_ARGS__) \
    )

    and it will work as you want it to.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Andrey Tarasevich@21:1/5 to Mark Summerfield on Sat Sep 21 12:17:15 2024
    On 09/21/24 12:35 AM, Mark Summerfield wrote:
    I have this macro:

    #define WARN(...) \
    do { \
    fprintf(stderr, "%s#%d: ", __FILE__, __LINE__); \
    fprintf(stderr, __VA_ARGS__); \
    } while (0);

    which I use like this:

    total++;
    if (failed) {
    WARN("failed because...");
    } else
    ok++;

    I would prefer to be able to write this instead:

    total++;
    if (failed)
    WARN("failed because...");
    else
    ok++;

    but doing so results in a compiler error:

    error: 'else' without a previous 'if'

    The whole idea of `do { ... } while(false)` idiom for writing complex
    macros is based on _not_ including that `;` after `while(false)` into
    the macro. Meanwhile, you botched the whole thing by adding that `;` there.

    Remove the trailing `;` from the macro and everything will work as you
    want it to.

    --
    Best regards,
    Andrey

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Andrey Tarasevich@21:1/5 to David Brown on Sat Sep 21 12:27:03 2024
    On 09/21/24 1:47 AM, David Brown wrote:

    You should get in the habit of being consistent with braces, and being generous with them.  Your future self with thank you.

    if (failed) {
        WARN("failed because...");
    } else {
        ok++;
    }


    Nope. There's absolutely no reason to overuse braces.

    And don't use "Egyptian" braces. The latter is actually an ill-begotten
    attempt to remedy the damage from the former. Just stop overusing
    braces, and there'll be no need for the remedy. Easy.

    This is the proper formatting style with braces

    if (failed)
    {
    ...
    }
    else
    {
    ...
    }

    The vertical spacing introduced by the `{` line provides separation
    between condition and the branch, which makes your code much more
    readable. It is also a very good location for a comment, if you decide
    to include one. Your future self with thank you.

    ... is small
    enough to fit entirely on a single line, and the statement could not
    possibly be misinterpreted, use a macro, or have any other non-obvious behaviour.

    Thus :

        if (failed) return -1;        // Early exit

    or

        if (!failed) ok++;

    Otherwise, put in all the braces.

    Nope. Do not ever write single-line `if` statements. This is a major
    impediment to step-by-step debugging.

    --
    Best regards,
    Andrey

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Bart@21:1/5 to Andrey Tarasevich on Sat Sep 21 21:11:21 2024
    On 21/09/2024 20:27, Andrey Tarasevich wrote:
    On 09/21/24 1:47 AM, David Brown wrote:

    You should get in the habit of being consistent with braces, and being
    generous with them.  Your future self with thank you.

    if (failed) {
         WARN("failed because...");
    } else {
         ok++;
    }


    Nope. There's absolutely no reason to overuse braces.

    And don't use "Egyptian" braces. The latter is actually an ill-begotten attempt to remedy the damage from the former. Just stop overusing
    braces, and there'll be no need for the remedy. Easy.

    This is the proper formatting style with braces

      if (failed)
      {
        ...
      }
      else
      {
        ...
      }

    The vertical spacing introduced by the `{` line provides separation
    between condition and the branch,

    Have a look at the middle of that example:

    } else {

    Here the braces serve no purpose; you already have 'else' separating the
    two branches to which you can add extra vertical space if you like.

    This is not just because of braces, you get the same thing with:

    end else begin

    Both are symptoms of the idea that any branch can only have a single
    statement, and if you need more, than you need a compound statement
    using {s1; s2; s3;} (unless you're Tim then you use s1, s2, s3 which may
    or may not work and is probably the worst of all).

    Since this is C, then if braces are to be mandatory, then at least allow
    people to write their code a little more compactly if they wish. In a
    language that allows proper statement sequences, you wouldn't commonly
    see this:

    if failed then

    s1

    else

    s2

    ...

    But this exactly how you are suggesting C should be written, when
    looking purely at the content: 50% blank lines.

    It looks ridiculous and those statements look very lonely!

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Opus@21:1/5 to Andrey Tarasevich on Sat Sep 21 22:39:10 2024
    On 21/09/2024 21:27, Andrey Tarasevich wrote:
    Nope. There's absolutely no reason to overuse braces.

    And don't use "Egyptian" braces. The latter is actually an ill-begotten attempt to remedy the damage from the former. Just stop overusing
    braces, and there'll be no need for the remedy. Easy.

    This is the proper formatting style with braces

    if (failed)
    {
    ...
    }
    else
    {
    ...
    }

    The vertical spacing introduced by the `{` line provides separation
    between condition and the branch, which makes your code much more
    readable. It is also a very good location for a comment, if you decide
    to include one. Your future self with thank you.
    I agree with that, but you realize you are kinda fighting
    "establishment" here. What you call "egyptian" braces is the so-called
    "TBS" which has infected the "default style" of approximately all
    programming languages that use braces. People use that almost
    religiously and the only rationale is to save space. Might have made
    sense 40 years ago when screen estate was a lot smaller, but these days,
    it's just madness. It's a lot less readable. The details are also odd:
    they seem to despise having an opening brace alone on a line, but they
    don't mind the closing brace to be.

    This is even worse: } else {
    starting a line with a closing symbol and ending it with an opening
    symbol, really?

    As to overuse, my own style and guideline is this: if both 'then' and
    'else' blocks are single statements, don't use braces.

    If any of these blocks have more than one statement, use braces for both
    to make it look consistent. Mixed braces in if/else do look terrible
    IMHO (and the lack of consistency always hinders readablity), like this:

    if (something)
    dothis();
    else
    {
    dothat();
    andalsothat();
    }

    Just avoid it.

    I've seen that code style guideline in various environments, so this
    isn't just my own either.

    Now the rationale for always using braces even for single statements at
    least makes some sense. Usually, it's for avoiding the case when a
    developer will add statements to a if or else block, forget to add
    braces to enclose it, and so that becomes a bug (which can't be easily
    trapped by compilers unless it's between a if and else. Some
    compilers/static analyzers, if you at least used proper indenting, will
    spot the indenting and lack of braces and will warn you about a
    potential mistake though.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Blue-Maned_Hawk@21:1/5 to Mark Summerfield on Sat Sep 21 21:18:07 2024
    Mark Summerfield wrote:

    I have this macro:

    #define WARN(...) \
    do { \
    fprintf(stderr, "%s#%d: ", __FILE__, __LINE__); \
    fprintf(stderr, __VA_ARGS__); \
    } while (0);

    which I use like this:

    total++;
    if (failed) {
    WARN("failed because...");
    } else
    ok++;

    I would prefer to be able to write this instead:

    total++;
    if (failed)
    WARN("failed because...");
    else
    ok++;

    but doing so results in a compiler error:

    error: 'else' without a previous 'if'

    Since the initial problem has already been solved by other messages,
    here's some extra completely unsolicited advice that you are free to
    ignore:

    If you intend for this macro to be invoked like how one would invoke the
    printf function (i.e. the arguments consisting of a format string literal followed by arguments to be formatted into it), you could get away with defining it like this instead:

    #define WARN(msg, ...) (fprintf(stderr, "%s#%d: " msg, __FILE__, __LINE__ __VA_OPT__(,) __VA_ARGS__))

    This would break if you try to invoke it with a nonliteral string, because
    this takes advantage of preprocessor adjacent string literal
    concatenation, but modern compilers tend to complain mightily if you try
    that anyway. It would have the advantage of expanding to an expression instead, which is often more beneficial for macros because it permits more flexibility in placement (something that i find unlikely to be relevant
    for this particular one, but which can't really particularly hurt to have anyway).

    --
    Blue-Maned_Hawk│shortens to Hawk│/blu.mɛin.dʰak/│he/him/his/himself/Mr. blue-maned_hawk.srht.site
    How do i run in these marrowy clogs?

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Andrey Tarasevich@21:1/5 to Keith Thompson on Sat Sep 21 20:05:51 2024
    On 09/21/24 2:54 PM, Keith Thompson wrote:

    One reason to "overuse" braces is that you can easily add another
    statement. If you write:

    if (failed)
        WARN("failed because...");
    else
        ok++;

    and later decide you need two statements in the else clause, you then
    need to add braces. If they're already there, you don't.

    Adding braces in this situation is _incomparably_ easier than splitting
    an annoying single-line `if` statement into multiple lines, discovered
    during an interactive debugging session. Which is something you yourself described as "easy enough" below.

    What you call "Egyptian" braces is the style used by the creators of the language

    Firstly, this is style. Being a "creator of the language" does not make
    one an authority on code formatting style.

    Secondly, most people pick up "the style used by the creators of the
    language" from the code samples used in the 2nd edition of K&R book.
    And, as we know, "the creators of the language" went a little lazy here.
    The samples were considered of "low importance" and fell victim to the tightening publishing schedules in front of the looming "threat" of the upcoming ANSI standard. The code samples were never properly updated to
    match the style and spirit of modern C.

    This is BTW, the reason we have to deal with that pesky and atrocious
    manner to cast the result of `malloc` - another practice erroneously
    believed to be "the style used by the creators of the language".

    and in a *lot* of open source software. Even if you don't like
    the style, you'll need to deal with it.
    I have my own fairly strong preferences about brace placement, but the
    most important rule is to follow the conventions of the code I'm working
    on.

    Certainly. It is not a good practice to force your own style onto
    someone else's code or an already existing code. Still, in most
    reasonably organized professional development environments personal
    preferences are normally welcomed with certain granularity. It is
    usually organized on "per translation unit" basis.

    --
    Best regards,
    Andrey

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From David Brown@21:1/5 to Andrey Tarasevich on Sun Sep 22 13:59:53 2024
    On 21/09/2024 21:27, Andrey Tarasevich wrote:
    On 09/21/24 1:47 AM, David Brown wrote:

    You should get in the habit of being consistent with braces, and being
    generous with them.  Your future self with thank you.

    To be clear here - many people have strong opinions about this topic,
    and there is no good evidence for claiming that one style is "better"
    than other styles. Different styles can have their pros and cons, and
    people will give different weightings to those pros and cons when
    choosing a style.

    So I fully respect your opinion here. But you are still wrong :-)


    if (failed) {
         WARN("failed because...");
    } else {
         ok++;
    }


    Nope. There's absolutely no reason to overuse braces.

    I am not suggesting overuse of braces. I am suggesting /good/ use of them.

    <https://www.synopsys.com/blogs/software-security/understanding-apple-goto-fail-vulnerability-2.html>

    That's perhaps the most famous example of the havoc caused by omitting
    useful braces.

    Consistency and clarity is important. So is maintainability. Suppose,
    for example, you want to add a line "attempts++;" alongside the "ok++;"
    line. When the braces are there, the change is exactly that - add the
    new line you want. Without the original braces, you are now making
    changes to the structural syntax of the code as well when you add in
    original braces - or you are making a mistake in the code.


    And don't use "Egyptian" braces. The latter is actually an ill-begotten attempt to remedy the damage from the former. Just stop overusing
    braces, and there'll be no need for the remedy. Easy.

    This is the proper formatting style with braces

      if (failed)
      {
        ...
      }
      else
      {
        ...
      }

    The vertical spacing introduced by the `{` line provides separation
    between condition and the branch, which makes your code much more
    readable. It is also a very good location for a comment, if you decide
    to include one. Your future self with thank you.

    No, it makes code longer and more tedious to read, and wastes
    significant vertical space so that you can see less code at a time. It
    leads people to think that it is a good idea to skip braces when they
    can. Put braces in a sensible place and there is no incentive to skip them.

    One important point for readability is to keep the conditionals
    relatively short so that the open brace is not far to the right - an
    overly complex expression is usually a bad idea anyway.


    ...  is small
    enough to fit entirely on a single line, and the statement could not
    possibly be misinterpreted, use a macro, or have any other non-obvious
    behaviour.

    Thus :

         if (failed) return -1;        // Early exit

    or

         if (!failed) ok++;

    Otherwise, put in all the braces.

    Nope. Do not ever write single-line `if` statements. This is a major impediment to step-by-step debugging.


    That is indeed true. Sometimes when you have code that you need to
    single-step or debug carefully, you need to express it a little
    differently or make syntactic changes to help. (A common one is to mark
    some of the local variables as "volatile".)

    I think it is reasonable to have such short one-line conditionals in
    simple cases, but it is certainly not a requirement - filling them out
    with the braces is fine too.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From David Brown@21:1/5 to Andrey Tarasevich on Sun Sep 22 14:15:28 2024
    On 22/09/2024 05:05, Andrey Tarasevich wrote:
    On 09/21/24 2:54 PM, Keith Thompson wrote:

    One reason to "overuse" braces is that you can easily add another
    statement.  If you write:

         if (failed)
              WARN("failed because...");
         else
              ok++;

    and later decide you need two statements in the else clause, you then
    need to add braces.  If they're already there, you don't.

    Adding braces in this situation is _incomparably_ easier than splitting
    an annoying single-line `if` statement into multiple lines, discovered
    during an interactive debugging session. Which is something you yourself described as "easy enough" below.

    I don't think "incomparably" is the word you are looking for -
    especially while making a comparison!

    Changes can always be made to code, and none of this is a particular
    challenge to do.


    What you call "Egyptian" braces is the style used by the creators of the
    language

    Firstly, this is style. Being a "creator of the language" does not make
    one an authority on code formatting style.


    Agreed.

    Secondly, most people pick up "the style used by the creators of the language" from the code samples used in the 2nd edition of K&R book.
    And, as we know, "the creators of the language" went a little lazy here.
    The samples were considered of "low importance" and fell victim to the tightening publishing schedules in front of the looming "threat" of the upcoming ANSI standard. The code samples were never properly updated to
    match the style and spirit of modern C.


    I can't speak for anyone else, but it is certainly not why I use this
    style. I have tried a few styles, I have seen many more, and it was a conscious decision about what I think makes code clearer to read and has
    the minimal risk of errors or misunderstandings.

    This is BTW, the reason we have to deal with that pesky and atrocious
    manner to cast the result of `malloc` - another practice erroneously
    believed to be "the style used by the creators of the language".

    There are plenty of design decisions in C that some people will think
    were a good idea, and others think are a bad idea. Let's not go there!


    and in a *lot* of open source software.  Even if you don't like
    the style, you'll need to deal with it.
    I have my own fairly strong preferences about brace placement, but the
    most important rule is to follow the conventions of the code I'm working
    on.


    Agreed.

    There's nothing worse than a git/subversion/whatever checkin when
    someone has changed the entire file to move around some braces or
    convert between their preferences of tabs or spaces.[1]

    Certainly. It is not a good practice to force your own style onto
    someone else's code or an already existing code. Still, in most
    reasonably organized professional development environments personal preferences are normally welcomed with certain granularity. It is
    usually organized on "per translation unit" basis.


    Practices vary somewhat. And while there's a fair variety of styles
    that can be seen as reasonable enough, it sometimes happens that the new
    person in a team has such a terrible style that they are forced to change.



    [1] Except, of course, a paper-cut. It's a well-established fact that
    there is nothing worse than a paper-cut!

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Kaz Kylheku@21:1/5 to David Brown on Sun Sep 22 15:11:56 2024
    On 2024-09-22, David Brown <[email protected]> wrote:
    I am not suggesting overuse of braces. I am suggesting /good/ use of them.

    <https://www.synopsys.com/blogs/software-security/understanding-apple-goto-fail-vulnerability-2.html>

    That's perhaps the most famous example of the havoc caused by omitting
    useful braces.

    Consistency and clarity is important. So is maintainability. Suppose,
    for example, you want to add a line "attempts++;" alongside the "ok++;"
    line. When the braces are there, the change is exactly that - add the
    new line you want. Without the original braces, you are now making
    changes to the structural syntax of the code as well when you add in
    original braces - or you are making a mistake in the code.

    My super advanced text editor from the future isn't letting me do that:

    if (failed)
    WARN("failed because...");
    else
    ok++;
    attempts++; // automatic deindent

    When I add a line after ok++, it deindents it to be at the same
    indentation level as the if, before letting me type any content into it.

    OK, I lied about the super advanced from the future. It's just Vim.

    Also GCC has been able to diagnose misleading indentation for some
    years now.

    Between those two, there is nothing to worry about; just concentrate on
    whether it looks prettier without the braces or with.

    --
    TXR Programming Language: http://nongnu.org/txr
    Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal
    Mastodon: @[email protected]

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Kenny McCormack@21:1/5 to [email protected] on Sun Sep 22 16:03:17 2024
    In article <[email protected]>,
    Kaz Kylheku <[email protected]> wrote:
    ...
    My super advanced text editor from the future isn't letting me do that:

    if (failed)
    WARN("failed because...");
    else
    ok++;
    attempts++; // automatic deindent

    When I add a line after ok++, it deindents it to be at the same
    indentation level as the if, before letting me type any content into it.

    OK, I lied about the super advanced from the future. It's just Vim.

    Also GCC has been able to diagnose misleading indentation for some
    years now.

    Between those two, there is nothing to worry about; just concentrate on >whether it looks prettier without the braces or with.

    Actually, there are more than a few C shibboleths that date back to the days
    of yore when both editors and C compilers were a lot less capable than they
    are today - with the result being, as you imply, that they are, nowadays, pretty much irrelevant.

    One such example is the old chestnut of:

    if (a = 0) ...

    My old Turbo C compiler caught this back in 1987.

    And yet people still talk about it today.

    --
    When I was growing up we called them "retards", but that's not PC anymore.
    Now, we just call them "Trump Voters".

    The question is, of course, how much longer it will be until that term is also un-PC.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Bart@21:1/5 to Kaz Kylheku on Sun Sep 22 16:56:47 2024
    On 22/09/2024 16:11, Kaz Kylheku wrote:
    On 2024-09-22, David Brown <[email protected]> wrote:
    I am not suggesting overuse of braces. I am suggesting /good/ use of them. >>
    <https://www.synopsys.com/blogs/software-security/understanding-apple-goto-fail-vulnerability-2.html>

    That's perhaps the most famous example of the havoc caused by omitting
    useful braces.

    Consistency and clarity is important. So is maintainability. Suppose,
    for example, you want to add a line "attempts++;" alongside the "ok++;"
    line. When the braces are there, the change is exactly that - add the
    new line you want. Without the original braces, you are now making
    changes to the structural syntax of the code as well when you add in
    original braces - or you are making a mistake in the code.

    My super advanced text editor from the future isn't letting me do that:

    if (failed)
    WARN("failed because...");
    else
    ok++;
    attempts++; // automatic deindent

    When I add a line after ok++, it deindents it to be at the same
    indentation level as the if, before letting me type any content into it.

    OK, I lied about the super advanced from the future. It's just Vim.

    Also GCC has been able to diagnose misleading indentation for some
    years now.

    Between those two, there is nothing to worry about; just concentrate on whether it looks prettier without the braces or with.


    So, everyone has to write code exactly to the C standard.

    But when it comes to more practical matters, it's OK to depend on the
    arbitrary characteristics and abilities of whichever one of 1001
    different text editors we happen to be using.

    Or we have to use a specific compiler with a specific set of options.

    Also GCC has been able to diagnose misleading indentation for some
    years now.

    How many years was that out of the last 52? How exactly do you turn it
    on? Since -Wall -Wpedantic -Wextra doesn't report it.

    It is a failure in the design of the language. You can't really depend
    on ad hoc features of the tools you use to create and compile source code.

    At least guidelines can be used such as always using braces, then errors
    can occur less often.

    (I've been bitten by this endless times when trying to add debugging
    statements to existing code. If that code consistently used braces, then
    it wouldn't happen.)

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From David Brown@21:1/5 to Kaz Kylheku on Sun Sep 22 18:03:46 2024
    On 22/09/2024 17:11, Kaz Kylheku wrote:
    On 2024-09-22, David Brown <[email protected]> wrote:
    I am not suggesting overuse of braces. I am suggesting /good/ use of them. >>
    <https://www.synopsys.com/blogs/software-security/understanding-apple-goto-fail-vulnerability-2.html>

    That's perhaps the most famous example of the havoc caused by omitting
    useful braces.

    Consistency and clarity is important. So is maintainability. Suppose,
    for example, you want to add a line "attempts++;" alongside the "ok++;"
    line. When the braces are there, the change is exactly that - add the
    new line you want. Without the original braces, you are now making
    changes to the structural syntax of the code as well when you add in
    original braces - or you are making a mistake in the code.

    My super advanced text editor from the future isn't letting me do that:

    if (failed)
    WARN("failed because...");
    else
    ok++;
    attempts++; // automatic deindent

    When I add a line after ok++, it deindents it to be at the same
    indentation level as the if, before letting me type any content into it.

    OK, I lied about the super advanced from the future. It's just Vim.

    Also GCC has been able to diagnose misleading indentation for some
    years now.

    Between those two, there is nothing to worry about; just concentrate on whether it looks prettier without the braces or with.


    I am happiest with a bracing style that looks good (in my subjective
    opinion), is easily understandable, is hard for humans to misinterpret,
    is automated to a large extent by many editors, and is checked by the
    compiler. I agree that mistakes due to indentation errors should be a
    thing of the past for people who use decent modern tools. But I'm a
    seatbelt and airbag kind of programmer, at least when there is no
    runtime cost - I prefer a method that is inherently hard to get wrong
    and is /also/ checked and automated by tools.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Michael S@21:1/5 to Bart on Sun Sep 22 19:27:26 2024
    On Sun, 22 Sep 2024 16:56:47 +0100
    Bart <[email protected]> wrote:

    On 22/09/2024 16:11, Kaz Kylheku wrote:
    On 2024-09-22, David Brown <[email protected]> wrote:
    I am not suggesting overuse of braces. I am suggesting /good/ use
    of them.

    <https://www.synopsys.com/blogs/software-security/understanding-apple-goto-fail-vulnerability-2.html>

    That's perhaps the most famous example of the havoc caused by
    omitting useful braces.

    Consistency and clarity is important. So is maintainability.
    Suppose, for example, you want to add a line "attempts++;"
    alongside the "ok++;" line. When the braces are there, the change
    is exactly that - add the new line you want. Without the original
    braces, you are now making changes to the structural syntax of the
    code as well when you add in original braces - or you are making a
    mistake in the code.

    My super advanced text editor from the future isn't letting me do
    that:

    if (failed)
    WARN("failed because...");
    else
    ok++;
    attempts++; // automatic deindent

    When I add a line after ok++, it deindents it to be at the same
    indentation level as the if, before letting me type any content
    into it.

    OK, I lied about the super advanced from the future. It's just Vim.

    Also GCC has been able to diagnose misleading indentation for some
    years now.

    Between those two, there is nothing to worry about; just
    concentrate on whether it looks prettier without the braces or with.


    So, everyone has to write code exactly to the C standard.

    But when it comes to more practical matters, it's OK to depend on the arbitrary characteristics and abilities of whichever one of 1001
    different text editors we happen to be using.

    Or we have to use a specific compiler with a specific set of options.

    Also GCC has been able to diagnose misleading indentation for some
    years now.

    How many years was that out of the last 52? How exactly do you turn
    it on? Since -Wall -Wpedantic -Wextra doesn't report it.


    My gcc warns just fine.

    void bar(int);
    int foo(int x) {
    if (x)
    bar(x);
    x -= 1;
    return x;
    }

    gcc -c -Wall foo.c

    foo.c: In function 'foo':
    foo.c:3:3: warning: this 'if' clause does not guard... [-Wmisleading-indentation] 3 | if (x)
    | ^~
    foo.c:5:5: note: ...this statement, but the latter is misleadingly
    indented as if it were guarded by the 'if'
    5 | x -= 1;
    | ^


    It is a failure in the design of the language. You can't really
    depend on ad hoc features of the tools you use to create and compile
    source code.

    At least guidelines can be used such as always using braces, then
    errors can occur less often.

    (I've been bitten by this endless times when trying to add debugging statements to existing code. If that code consistently used braces,
    then it wouldn't happen.)

    I wonder why I was not bitten by that more than, may be, 5 times in
    30+ years. Probably, I am doing something wrong.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Bart@21:1/5 to Michael S on Sun Sep 22 17:47:23 2024
    On 22/09/2024 17:27, Michael S wrote:
    On Sun, 22 Sep 2024 16:56:47 +0100
    Bart <[email protected]> wrote:

    On 22/09/2024 16:11, Kaz Kylheku wrote:
    On 2024-09-22, David Brown <[email protected]> wrote:
    I am not suggesting overuse of braces. I am suggesting /good/ use
    of them.

    <https://www.synopsys.com/blogs/software-security/understanding-apple-goto-fail-vulnerability-2.html>

    That's perhaps the most famous example of the havoc caused by
    omitting useful braces.

    Consistency and clarity is important. So is maintainability.
    Suppose, for example, you want to add a line "attempts++;"
    alongside the "ok++;" line. When the braces are there, the change
    is exactly that - add the new line you want. Without the original
    braces, you are now making changes to the structural syntax of the
    code as well when you add in original braces - or you are making a
    mistake in the code.

    My super advanced text editor from the future isn't letting me do
    that:

    if (failed)
    WARN("failed because...");
    else
    ok++;
    attempts++; // automatic deindent

    When I add a line after ok++, it deindents it to be at the same
    indentation level as the if, before letting me type any content
    into it.

    OK, I lied about the super advanced from the future. It's just Vim.

    Also GCC has been able to diagnose misleading indentation for some
    years now.

    Between those two, there is nothing to worry about; just
    concentrate on whether it looks prettier without the braces or with.


    So, everyone has to write code exactly to the C standard.

    But when it comes to more practical matters, it's OK to depend on the
    arbitrary characteristics and abilities of whichever one of 1001
    different text editors we happen to be using.

    Or we have to use a specific compiler with a specific set of options.

    > Also GCC has been able to diagnose misleading indentation for some
    > years now.

    How many years was that out of the last 52? How exactly do you turn
    it on? Since -Wall -Wpedantic -Wextra doesn't report it.


    My gcc warns just fine.

    void bar(int);
    int foo(int x) {
    if (x)
    bar(x);
    x -= 1;
    return x;
    }

    gcc -c -Wall foo.c

    foo.c: In function 'foo':
    foo.c:3:3: warning: this 'if' clause does not guard... [-Wmisleading-indentation] 3 | if (x)
    | ^~
    foo.c:5:5: note: ...this statement, but the latter is misleadingly
    indented as if it were guarded by the 'if'
    5 | x -= 1;
    | ^


    That doesn't pick up a program that in my editor looks like this:

    ------------------------
    int main(void){
    total++;
    if (failed)
    WARN("failed because...");
    else
    ok++;
    failed=0;
    }
    ------------------------

    However, the first two indents use four spaces, but the third uses a
    hard tab that my editor shows as four spaces, but if I print it out to
    the console, it shows this:

    ------------------------
    int main(void){
    total++;
    if (failed)
    WARN("failed because...");
    else
    ok++;
    failed=0;
    }
    ------------------------

    That odd indentation is not picked up either. But it will say something
    if all indents used spaces or used hard tabs.

    If the language has explicit block delimiters (either mandatory braces,
    or endings like 'end'), then the problem simply wouldn't arise. That
    'failed=0' line would either be before the delimiter or after it. The
    original example would look something like this:


    ------------------------
    if (failed) {
    WARN("failed because...");
    } else {
    ok++;
    }
    failed=0;
    ------------------------
    That line is still mis-indented, but is now less likely to be taken to
    be part of that 'else' block.






    It is a failure in the design of the language. You can't really
    depend on ad hoc features of the tools you use to create and compile
    source code.

    At least guidelines can be used such as always using braces, then
    errors can occur less often.

    (I've been bitten by this endless times when trying to add debugging
    statements to existing code. If that code consistently used braces,
    then it wouldn't happen.)

    I wonder why I was not bitten by that more than, may be, 5 times in
    30+ years. Probably, I am doing something wrong.

    How you tried to debug other people's code via adding printf statements
    at strategic points?

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From David Brown@21:1/5 to Keith Thompson on Mon Sep 23 08:16:07 2024
    On 22/09/2024 22:39, Keith Thompson wrote:
    Bart <[email protected]> writes:
    On 22/09/2024 16:11, Kaz Kylheku wrote:
    [...]
    Also GCC has been able to diagnose misleading indentation for some
    years now.

    How many years was that out of the last 52? How exactly do you turn it
    on? Since -Wall -Wpedantic -Wextra doesn't report it.

    The -Wmisleading-indentation option was added to gcc on 2015-05-12,
    and incorporated into -Wall 2015-12-10. gcc 6.1.0 has the option
    and includes it in -Wall; gcc 5.3.0 does not. (Are you using a gcc
    release that old?) It uses the -ftabstop= option (defaulting to 8)
    to determine whether indentation lines up or not.

    Inconsistent tabstops and mixing of spaces and tabs can certainly
    cause problems.


    That would be detected quite easily if the default for -ftabstop were,
    say, 27. Then the chance of accidentally matching indents with tabs and
    spaces would be negligible.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Richard Harnden@21:1/5 to David Brown on Mon Sep 23 08:06:34 2024
    On 23/09/2024 07:16, David Brown wrote:
    On 22/09/2024 22:39, Keith Thompson wrote:
    Bart <[email protected]> writes:
    On 22/09/2024 16:11, Kaz Kylheku wrote:
    [...]
    Also GCC has been able to diagnose misleading indentation for some
    years now.

    How many years was that out of the last 52? How exactly do you turn it
    on? Since -Wall -Wpedantic -Wextra doesn't report it.

    The -Wmisleading-indentation option was added to gcc on 2015-05-12,
    and incorporated into -Wall 2015-12-10.  gcc 6.1.0 has the option
    and includes it in -Wall; gcc 5.3.0 does not.  (Are you using a gcc
    release that old?)  It uses the -ftabstop= option (defaulting to 8)
    to determine whether indentation lines up or not.

    Inconsistent tabstops and mixing of spaces and tabs can certainly
    cause problems.


    That would be detected quite easily if the default for -ftabstop were,
    say, 27.  Then the chance of accidentally matching indents with tabs and spaces would be negligible.


    Isn't that the opposite of what you want, though?

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From David Brown@21:1/5 to Richard Harnden on Mon Sep 23 11:14:07 2024
    On 23/09/2024 09:06, Richard Harnden wrote:
    On 23/09/2024 07:16, David Brown wrote:
    On 22/09/2024 22:39, Keith Thompson wrote:
    Bart <[email protected]> writes:
    On 22/09/2024 16:11, Kaz Kylheku wrote:
    [...]
    Also GCC has been able to diagnose misleading indentation for some
    years now.

    How many years was that out of the last 52? How exactly do you turn it >>>> on? Since -Wall -Wpedantic -Wextra doesn't report it.

    The -Wmisleading-indentation option was added to gcc on 2015-05-12,
    and incorporated into -Wall 2015-12-10.  gcc 6.1.0 has the option
    and includes it in -Wall; gcc 5.3.0 does not.  (Are you using a gcc
    release that old?)  It uses the -ftabstop= option (defaulting to 8)
    to determine whether indentation lines up or not.

    Inconsistent tabstops and mixing of spaces and tabs can certainly
    cause problems.


    That would be detected quite easily if the default for -ftabstop were,
    say, 27.  Then the chance of accidentally matching indents with tabs
    and spaces would be negligible.


    Isn't that the opposite of what you want, though?


    What I would be looking for in this case is a warning if I had used tabs
    and spaces (for indents) at different places in the code. If the tab
    setting is a sensible choice - typically 4 or 8 spaces worth - then you
    can easily have code that looks right (in the sense of having visual
    indents that match the real block structure) with one setting and looks
    wrong with a different setting.

    For example, you might write this code :

    <tb>if (test)
    <tb><tb>foo();
    < >< >bar();

    You've made an error here - you had intended to have both calls within
    the conditional. With 4 spaces per tab when you made the error, this
    could be spotted by tools using tabstop settings of 4, or by a code
    reviewer with those settings.

    However, to tools or code reviewers with tabstop settings of 8, the code
    would appear as:

    <tb >if (test)
    <tb ><tb >foo();
    < >< >bar();

    Now the indentation matches the syntactical structure, and the mistake
    is missed.

    With a tabstop of 27, the "if" and "bar()" lines do not match up, and
    the mistake can be flagged.

    Of course a tabstop of 27 is not necessary - anything other than a sane
    value of 4 or 8 would catch almost anything. But having a bit of extra distance also catches cases of tab then space typos.

    And there could also be a warning that checked directly for mixes of
    tabs and spaces in indents. But such mixes can happen when moving or
    copying code between files, and there are some people who like to mix
    8-space tabs with 4 explicit spaces in their code.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Richard Harnden@21:1/5 to David Brown on Mon Sep 23 11:37:34 2024
    On 23/09/2024 10:14, David Brown wrote:
    On 23/09/2024 09:06, Richard Harnden wrote:
    On 23/09/2024 07:16, David Brown wrote:
    On 22/09/2024 22:39, Keith Thompson wrote:
    Bart <[email protected]> writes:
    On 22/09/2024 16:11, Kaz Kylheku wrote:
    [...]
    Also GCC has been able to diagnose misleading indentation for some >>>>>> years now.

    How many years was that out of the last 52? How exactly do you turn it >>>>> on? Since -Wall -Wpedantic -Wextra doesn't report it.

    The -Wmisleading-indentation option was added to gcc on 2015-05-12,
    and incorporated into -Wall 2015-12-10.  gcc 6.1.0 has the option
    and includes it in -Wall; gcc 5.3.0 does not.  (Are you using a gcc
    release that old?)  It uses the -ftabstop= option (defaulting to 8)
    to determine whether indentation lines up or not.

    Inconsistent tabstops and mixing of spaces and tabs can certainly
    cause problems.


    That would be detected quite easily if the default for -ftabstop
    were, say, 27.  Then the chance of accidentally matching indents with
    tabs and spaces would be negligible.


    Isn't that the opposite of what you want, though?


    What I would be looking for in this case is a warning if I had used tabs
    and spaces (for indents) at different places in the code.  If the tab setting is a sensible choice - typically 4 or 8 spaces worth - then you
    can easily have code that looks right (in the sense of having visual
    indents that match the real block structure) with one setting and looks
    wrong with a different setting.

    For example, you might write this code :

    <tb>if (test)
    <tb><tb>foo();
    <  ><  >bar();

    You've made an error here - you had intended to have both calls within
    the conditional.  With 4 spaces per tab when you made the error, this
    could be spotted by tools using tabstop settings of 4, or by a code
    reviewer with those settings.

    However, to tools or code reviewers with tabstop settings of 8, the code would appear as:

    <tb    >if (test)
    <tb    ><tb    >foo();
    <  ><  >bar();

    Now the indentation matches the syntactical structure, and the mistake
    is missed.

    With a tabstop of 27, the "if" and "bar()" lines do not match up, and
    the mistake can be flagged.

    Of course a tabstop of 27 is not necessary - anything other than a sane
    value of 4 or 8 would catch almost anything.  But having a bit of extra distance also catches cases of tab then space typos.

    And there could also be a warning that checked directly for mixes of
    tabs and spaces in indents.  But such mixes can happen when moving or copying code between files, and there are some people who like to mix
    8-space tabs with 4 explicit spaces in their code.


    If -ftabstops doesn't agree with your editor setting,
    then gcc misses the errors, eg:

    gcc, with the default -ftabstop=8, sees this ...

    $ expand -t8 x.c
    #include <stdio.h>

    int main(void)
    {
    int x=1;

    if ( x == 1 )
    printf("x is 1\n");
    else
    printf("x is not 1\n"); // tabs
    printf("x is %d\n", x); // spaces

    return 0;
    }

    ... and the indentation doesn't match up, so it's happy.

    $ gcc -Wmisleading-indentation -ftabstop=8 x.c
    (nothing)

    But, in my editor, I see this ...

    $ expand -t4 x.c
    #include <stdio.h>

    int main(void)
    {
    int x=1;

    if ( x == 1 )
    printf("x is 1\n");
    else
    printf("x is not 1\n"); // tabs
    printf("x is %d\n", x); // spaces

    return 0;
    }

    ... and then indentation does match up, so I want the error flagged.
    Which it does:

    $ gcc -Wmisleading-indentation -ftabstop=4 x.c
    x.c: In function ‘main’:
    x.c:9:5: warning: this ‘else’ clause does not guard... [-Wmisleading-indentation]
    9 | else
    | ^~~~
    x.c:11:9: note: ...this statement, but the latter is misleadingly
    indented as if it were guarded by the ‘else’
    11 | printf("x is %d\n", x); // spaces
    | ^~~~~~

    So, to me anyway, telling gcc that tabstops are 27 would suppress all
    the useful warnings.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From David Brown@21:1/5 to Richard Harnden on Mon Sep 23 14:22:30 2024
    On 23/09/2024 12:37, Richard Harnden wrote:

    So, to me anyway, telling gcc that tabstops are 27 would suppress all
    the useful warnings.


    I see what you mean.

    Fair enough - it seems that picking a tabstop setting that matches your
    editor settings could catch some mistakes that a different tabstop
    setting would not. Equally, I think from my example, having a different tabstop setting would catch other errors that one matching your editor
    would not.

    And in my brief testing, using gcc 13, it failed to catch several cases
    of indentation mismatches, regardless of the tabstop setting, which is a
    bit disappointing.

    I think perhaps the best solution would be for gcc to warn about
    space/tab mismatches as well, regardless of the tabstop settings.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Tim Rentsch@21:1/5 to [email protected] on Tue Sep 24 06:18:08 2024
    Blue-Maned_Hawk <[email protected]d> writes:

    Mark Summerfield wrote:

    I have this macro:

    #define WARN(...) \
    do { \
    fprintf(stderr, "%s#%d: ", __FILE__, __LINE__); \
    fprintf(stderr, __VA_ARGS__); \
    } while (0);

    which I use like this:

    total++;
    if (failed) {
    WARN("failed because...");
    } else
    ok++;

    I would prefer to be able to write this instead:

    total++;
    if (failed)
    WARN("failed because...");
    else
    ok++;

    but doing so results in a compiler error:

    error: 'else' without a previous 'if'

    Since the initial problem has already been solved by other messages,
    here's some extra completely unsolicited advice that you are free to
    ignore:

    If you intend for this macro to be invoked like how one would
    invoke the printf function (i.e. the arguments consisting of a
    format string literal followed by arguments to be formatted into
    it), you could get away with defining it like this instead:

    #define WARN(msg, ...) (fprintf(stderr, "%s#%d: " msg, __FILE__, __LINE__ __VA_OPT__(,) __VA_ARGS__))

    This would break if you try to invoke it with a nonliteral string,
    because this takes advantage of preprocessor adjacent string
    literal concatenation, but modern compilers tend to complain
    mightily if you try that anyway. It would have the advantage of
    expanding to an expression instead, which is often more beneficial
    for macros because it permits more flexibility in placement
    (something that i find unlikely to be relevant for this particular
    one, but which can't really particularly hurt to have anyway).

    The alternative below works without needing __VA_OPT__, in earlier
    C standards including C90.


    #include <stdarg.h>
    #include <stdio.h>

    #define WARN(...) (warning_with_origin( __FILE__, __LINE__, __VA_ARGS__ ))

    int
    warning_with_origin( const char *file, long line, const char *format, ... ){
    va_list ap;

    int a = (va_start( ap, format ), 0);
    int b = a < 0 ? a : fprintf( stderr, "%s#%ld: ", file, line );
    int c = b < 0 ? b : vfprintf( stderr, format, ap );
    int d = c < 0 ? c : fprintf( stderr, "\n" );

    return va_end( ap ), d < 0 ? d : a + b + c + d;
    }

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Tim Rentsch@21:1/5 to Michael S on Tue Sep 24 07:36:39 2024
    Michael S <[email protected]> writes:

    On Sun, 22 Sep 2024 16:56:47 +0100
    Bart <[email protected]> wrote:

    On 22/09/2024 16:11, Kaz Kylheku wrote:

    On 2024-09-22, David Brown <[email protected]> wrote:

    I am not suggesting overuse of braces. I am suggesting /good/ use
    of them.

    <https://www.synopsys.com/blogs/software-security/
    understanding-apple-goto-fail-vulnerability-2.html>

    That's perhaps the most famous example of the havoc caused by
    omitting useful braces.

    Consistency and clarity is important. So is maintainability.
    Suppose, for example, you want to add a line "attempts++;"
    alongside the "ok++;" line. When the braces are there, the change
    is exactly that - add the new line you want. Without the original
    braces, you are now making changes to the structural syntax of the
    code as well when you add in original braces - or you are making a
    mistake in the code.

    My super advanced text editor from the future isn't letting me do
    that:

    if (failed)
    WARN("failed because...");
    else
    ok++;
    attempts++; // automatic deindent

    When I add a line after ok++, it deindents it to be at the same
    indentation level as the if, before letting me type any content
    into it.

    OK, I lied about the super advanced from the future. It's just
    Vim.

    Also GCC has been able to diagnose misleading indentation for some
    years now.

    Between those two, there is nothing to worry about; just
    concentrate on whether it looks prettier without the braces or
    with.

    So, everyone has to write code exactly to the C standard.

    But when it comes to more practical matters, it's OK to depend on
    the arbitrary characteristics and abilities of whichever one of
    1001 different text editors we happen to be using.

    Or we have to use a specific compiler with a specific set of
    options.

    Also GCC has been able to diagnose misleading indentation for some
    years now.

    How many years was that out of the last 52? How exactly do you
    turn it on? Since -Wall -Wpedantic -Wextra doesn't report it.

    My gcc warns just fine.

    void bar(int);
    int foo(int x) {
    if (x)
    bar(x);
    x -= 1;
    return x;
    }

    gcc -c -Wall foo.c

    foo.c: In function 'foo':
    foo.c:3:3: warning: this 'if' clause does not guard... [-Wmisleading-indentation] 3 | if (x)
    | ^~
    foo.c:5:5: note: ...this statement, but the latter is misleadingly
    indented as if it were guarded by the 'if'
    5 | x -= 1;
    | ^


    It is a failure in the design of the language. You can't really
    depend on ad hoc features of the tools you use to create and
    compile source code.

    At least guidelines can be used such as always using braces, then
    errors can occur less often.

    (I've been bitten by this endless times when trying to add
    debugging statements to existing code. If that code consistently
    used braces, then it wouldn't happen.)

    I wonder why I was not bitten by that more than, may be, 5 times
    in 30+ years. Probably, I am doing something wrong.

    My long-standing habit is to write this

    if(x) bar(x);

    or this

    if(x){
    bar(x);
    }

    but never this

    if(x)
    bar(x);

    The reason for this habit is that many years ago I got bitten by
    trying to add a line in the last case. The habit subsequently
    adopted has proven very effective at eliminating such errors.

    The idea of changing the language to always require braces is
    unnecessary and wasteful (besides being a non-starter for purely
    practical reasons).

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Andrey Tarasevich@21:1/5 to Tim Rentsch on Tue Sep 24 07:52:02 2024
    On 09/24/24 7:36 AM, Tim Rentsch wrote:

    My long-standing habit is to write this

    if(x) bar(x);

    or this

    if(x){
    bar(x);
    }

    but never this

    if(x)
    bar(x);

    The reason for this habit is that many years ago I got bitten by
    trying to add a line in the last case. The habit subsequently
    adopted has proven very effective at eliminating such errors.


    It is just weird.

    This is no different from insisting in using "Yoda conditions", claiming
    that "many years ago I was bitten by an accidental = in place of ==". In reality we all know that regardless of how many scary stories someone
    might tell about dangers of accidental assignment in place of
    comparison, it just does not happen. There's no such issue. People just
    don't make this mistake.

    The same applies to

    if(x)
    bar(x);

    This is the right thing to do. It is the most readable and elegant way
    to write a simple `if`. And the dreaded "one day you will add a line and suffer" just doesn't happen. There's no such issue. People just don't
    make this mistake.

    --
    Best regards,
    Andrey

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From David Brown@21:1/5 to Andrey Tarasevich on Tue Sep 24 17:24:32 2024
    On 24/09/2024 16:52, Andrey Tarasevich wrote:
    On 09/24/24 7:36 AM, Tim Rentsch wrote:

    My long-standing habit is to write this

        if(x)  bar(x);

    or this

        if(x){
           bar(x);
        }

    but never this

        if(x)
           bar(x);

    The reason for this habit is that many years ago I got bitten by
    trying to add a line in the last case.  The habit subsequently
    adopted has proven very effective at eliminating such errors.


    It is just weird.

    This is no different from insisting in using "Yoda conditions", claiming
    that "many years ago I was bitten by an accidental = in place of ==". In reality we all know that regardless of how many scary stories someone
    might tell about dangers of accidental assignment in place of
    comparison, it just does not happen. There's no such issue. People just
    don't make this mistake.

    They do.

    You might not do so, but other people do. Not often, but still too often.

    (I don't think Yoda conditions are the answer here - automatic checking
    from tools is simple enough.)


    The same applies to

      if(x)
        bar(x);

    This is the right thing to do. It is the most readable and elegant way
    to write a simple `if`. And the dreaded "one day you will add a line and suffer" just doesn't happen. There's no such issue. People just don't
    make this mistake.


    Again, people do.

    I gave you a link earlier to a hugely costly example of this mistake,
    made by very experienced C programmers.

    But I am confident that Tim, and others (like me) who use a similar
    style, are almost entirely immune to this particular mistake.

    Now, if there were a good way to automatically detect mixups between &
    and &&, | and ||, then we'd be rid of a number of these kinds of errors
    in C coding.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Bart@21:1/5 to Andrey Tarasevich on Tue Sep 24 17:22:25 2024
    On 24/09/2024 15:52, Andrey Tarasevich wrote:
    On 09/24/24 7:36 AM, Tim Rentsch wrote:

    My long-standing habit is to write this

        if(x)  bar(x);

    or this

        if(x){
           bar(x);
        }

    but never this

        if(x)
           bar(x);

    The reason for this habit is that many years ago I got bitten by
    trying to add a line in the last case.  The habit subsequently
    adopted has proven very effective at eliminating such errors.


    It is just weird.

    This is no different from insisting in using "Yoda conditions", claiming
    that "many years ago I was bitten by an accidental = in place of ==". In reality we all know that regardless of how many scary stories someone
    might tell about dangers of accidental assignment in place of
    comparison, it just does not happen. There's no such issue. People just
    don't make this mistake.

    The same applies to

      if(x)
        bar(x);

    This is the right thing to do. It is the most readable and elegant way
    to write a simple `if`.

    Well, it is the ONLY way C provides to write the branches of an
    if-statement. Each only takes a single statement.

    For more than one statement in a branch, they have to be enclosed in a
    compound statement with braces.

    And the dreaded "one day you will add a line and
    suffer" just doesn't happen. There's no such issue.

    No, this must happen ALL THE TIME. That is, you write one statement,
    then decide you need more than one. Or you start with 3 statements and
    get rid of two of them.

    So, what happens: is there are some of sort dance where you add {,}
    braces when N increases beyond 1, and remove them when N reaches 1 again?

    What happens when N changes from 1 to 0 (eg. a statement is temporarily commented out? Without braces, this will causes problems (unless somehow
    you have its closing";" on its own line), because then the following
    statement is taken to be the branch, with an additional problem if
    'else' actually follows.

    I haven't even got to the bit where you might make a mistake that is not
    picked up by a compiler.

    It's a just one big palaver that can solved easily by always using a
    compound statement which has opening and closing braces. Within such a statement, N can vary between 0, 1 and any other number, any of
    combination can be commented out, without needing to take any special
    action.

    It can also happen that when starting to write a branch, you don't know
    what N is going to be, or maybe the statements will be filled in later.
    Here it is useful to have {} as a placeholder for those statements.



    People just don't
    make this mistake.

    And there is that too. Maybe YOU don't make it, in the same way that you probably know all the binary operator precedences by heart and never get
    them wrong. Well, not everyone is perfect.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Bart@21:1/5 to Tim Rentsch on Tue Sep 24 17:35:28 2024
    On 24/09/2024 15:36, Tim Rentsch wrote:
    Michael S <[email protected]> writes:


    The idea of changing the language to always require braces is
    unnecessary and wasteful (besides being a non-starter for purely
    practical reasons).

    Well, practically it is not difficult.

    I started modifying my compiler to do it, but found I already had that
    option, which was a hard-coded value in the source. It took a minute to reenable it. Support for it requires 2-3 lines of code.

    However, that makes an exception for if-else chains, so that you can
    still write:

    if (c1) {} else if (c2) {} else if (c3) {}

    instead of needing:

    if (c1) {} else {if (c2) {} else {if (c3) {}}}

    (Maybe the language needs a construct like 'elif', as is used in
    languages like, say, C's own preprocessor! HTH did that end up with the sensible syntax while the main language was stuck with the rubbish one?)

    BTW with mandatory braces enforced, my generated-C applications still
    build with no problems. Because generated code always uses braces. There
    is no point in leaving them out, other than perhaps ending up with 0.5%
    smaller output.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Bart@21:1/5 to Keith Thompson on Tue Sep 24 20:42:55 2024
    On 24/09/2024 20:30, Keith Thompson wrote:
    Bart <[email protected]> writes:
    On 24/09/2024 15:36, Tim Rentsch wrote:
    Michael S <[email protected]> writes:
    The idea of changing the language to always require braces is
    unnecessary and wasteful (besides being a non-starter for purely
    practical reasons).

    Well, practically it is not difficult.

    Changing a compiler to require compound statements would not be
    difficult. Changing the language in that way would be completely impractical, because it would break existing code.

    But not new code that uses compound statements, which is will still be compatible with compilers that don't enforce it.

    And as I said, it doesn't break my generated code, and the first
    substantial manually written program I tried worked too.

    Adding such an option, if it doesn't already exist, would be trivial.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Kaz Kylheku@21:1/5 to Bart on Tue Sep 24 19:59:30 2024
    On 2024-09-24, Bart <[email protected]> wrote:
    (Maybe the language needs a construct like 'elif', as is used in

    The language doesn't need such a construct in order for a compiler
    to implement it internally.

    You just have to treat the token sequence else if as a supertoken.

    Doing it at the grammar level may require two symbols of lookahead,
    which is a a problem for off-the-shelf parser generation tooling based
    on LALR(1) and whatnot.

    A possible trick is to handle it at the lexical level. The pattern
    else{WSP}if can be recognized as a single token, assigned its own
    enumeration symbol. {WSP} is arbitrary whitespace. (We assume
    comments have been stripped by a lower preprocessing phase.)

    --
    TXR Programming Language: http://nongnu.org/txr
    Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal
    Mastodon: @[email protected]

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Bart@21:1/5 to Kaz Kylheku on Tue Sep 24 21:12:28 2024
    On 24/09/2024 20:59, Kaz Kylheku wrote:
    On 2024-09-24, Bart <[email protected]> wrote:
    (Maybe the language needs a construct like 'elif', as is used in

    The language doesn't need such a construct in order for a compiler
    to implement it internally.

    You just have to treat the token sequence else if as a supertoken.

    Doing it at the grammar level may require two symbols of lookahead,
    which is a a problem for off-the-shelf parser generation tooling based
    on LALR(1) and whatnot.

    That sounds as much of a hack as making a special case for 'else if' so
    that it doesn't need 'else {if' (and a matching } later on) when
    enforcing compound statements for such blocks.

    One consequence of how it works now is that if I write:

    if (a) {}
    else if (b) {}
    else if (c) {}
    else {}

    then use a tool I have to visualise C code in my syntax, it generates:

    if a then
    else
    if b then
    else
    if c then
    else
    fi
    fi
    fi

    The nested nature is revealed. If there were 50 'else if' links, the
    output would disappear off to the right.

    With elif, elsif etc, the compiler has the option to keep the internal structure linear (which also means it will not put pressure on the stack
    if somebody decides to write a million of them).

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Kaz Kylheku@21:1/5 to Bart on Tue Sep 24 22:36:53 2024
    On 2024-09-24, Bart <[email protected]> wrote:
    On 24/09/2024 20:59, Kaz Kylheku wrote:
    On 2024-09-24, Bart <[email protected]> wrote:
    (Maybe the language needs a construct like 'elif', as is used in

    The language doesn't need such a construct in order for a compiler
    to implement it internally.

    You just have to treat the token sequence else if as a supertoken.

    Doing it at the grammar level may require two symbols of lookahead,
    which is a a problem for off-the-shelf parser generation tooling based
    on LALR(1) and whatnot.

    That sounds as much of a hack as making a special case for 'else if' so
    that it doesn't need 'else {if' (and a matching } later on) when
    enforcing compound statements for such blocks.

    It's a hack, but you can completely hide it at the grammar level; you
    can write your grammar with the assumption that there is an ELIF token,
    so that the syntax is identical to that found in languages that have
    elif or elsif. Just the lexical level, it is spelled by two words.

    One consequence of how it works now is that if I write:

    if (a) {}
    else if (b) {}
    else if (c) {}
    else {}

    then use a tool I have to visualise C code in my syntax, it generates:

    It behooves C processing tools to grok "else if" where it makes sense.

    if a then
    else
    if b then
    else
    if c then
    else
    fi
    fi
    fi

    Note that in this type of language, an "elif" is helpful, because
    every "else if" introduces an "if", which must be matched by its own
    "fi", whereas an "elif" doesn't require its own closing keyword.

    In other words, "elif" is more than just a contraction for "else if"; it eliminates "fi".

    In the preprocessor, it is different; there is an #endif.

    If the above language has elif, then a conversion can be applied
    by the rewrite rule

    {if/elif} A then B else if C then [...] fi fi

    ->

    {if/elif} A then B elif C then [...] fi

    this can be repeatedly applied until there is no match for the
    left hand side.

    The nested nature is revealed. If there were 50 'else if' links, the
    output would disappear off to the right.

    With elif, elsif etc, the compiler has the option to keep the internal structure linear (which also means it will not put pressure on the stack
    if somebody decides to write a million of them).

    The option to keep the AST structure linear is there regardless,
    as I pointed out; compilers writers can easily pretend that "else if"
    is special.

    --
    TXR Programming Language: http://nongnu.org/txr
    Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal
    Mastodon: @[email protected]

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Tim Rentsch@21:1/5 to Andrey Tarasevich on Sat Sep 28 05:02:05 2024
    Andrey Tarasevich <[email protected]> writes:

    [...]

    And don't use "Egyptian" braces [the style used in the
    first edition of The C Programming Language, by Kernighan
    and Ritchie].

    This is the proper formatting style with braces

    if (failed)
    {
    ...
    }
    else
    {
    ...
    }

    The vertical spacing introduced by the `{` line provides
    separation between condition and the branch, which makes
    your code much more readable. [...]

    What qualities does this layout style have that make it "more
    readable", other than it being one that you like or prefer?

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Michael S@21:1/5 to Tim Rentsch on Sat Sep 28 20:30:48 2024
    On Sat, 28 Sep 2024 05:02:05 -0700
    Tim Rentsch <[email protected]> wrote:

    Andrey Tarasevich <[email protected]> writes:

    [...]

    And don't use "Egyptian" braces [the style used in the
    first edition of The C Programming Language, by Kernighan
    and Ritchie].

    This is the proper formatting style with braces

    if (failed)
    {
    ...
    }
    else
    {
    ...
    }

    The vertical spacing introduced by the `{` line provides
    separation between condition and the branch, which makes
    your code much more readable. [...]

    What qualities does this layout style have that make it "more
    readable", other than it being one that you like or prefer?

    { at the same level of indentation as its matching }

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Andrey Tarasevich@21:1/5 to Tim Rentsch on Sat Sep 28 21:02:11 2024
    On 09/28/24 5:02 AM, Tim Rentsch wrote:
    Andrey Tarasevich <[email protected]> writes:

    [...]

    And don't use "Egyptian" braces [the style used in the
    first edition of The C Programming Language, by Kernighan
    and Ritchie].

    This is the proper formatting style with braces

    if (failed)
    {
    ...
    }
    else
    {
    ...
    }

    The vertical spacing introduced by the `{` line provides
    separation between condition and the branch, which makes
    your code much more readable. [...]

    What qualities does this layout style have that make it "more
    readable", other than it being one that you like or prefer?

    Er... The answer to his question is already present in the quoted
    portion of my post. "The vertical spacing introduced..."

    --
    Best regards,
    Andrey

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Tim Rentsch@21:1/5 to Michael S on Sat Sep 28 21:53:06 2024
    Michael S <[email protected]> writes:

    On Sat, 28 Sep 2024 05:02:05 -0700
    Tim Rentsch <[email protected]> wrote:

    Andrey Tarasevich <[email protected]> writes:

    [...]

    And don't use "Egyptian" braces [the style used in the
    first edition of The C Programming Language, by Kernighan
    and Ritchie].

    This is the proper formatting style with braces

    if (failed)
    {
    ...
    }
    else
    {
    ...
    }

    The vertical spacing introduced by the `{` line provides
    separation between condition and the branch, which makes
    your code much more readable. [...]

    What qualities does this layout style have that make it "more
    readable", other than it being one that you like or prefer?

    { at the same level of indentation as its matching }

    Certainly it is true that the layout style shown has the open
    brace at the same level of indentation as the matching close
    brace. What about that property makes this layout "more
    readable"? The statement given sounds like a tautology -
    I don't see that any new information has been added.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Tim Rentsch@21:1/5 to Andrey Tarasevich on Sat Sep 28 22:47:16 2024
    Andrey Tarasevich <[email protected]> writes:

    On 09/28/24 5:02 AM, Tim Rentsch wrote:

    Andrey Tarasevich <[email protected]> writes:

    [...]

    And don't use "Egyptian" braces [the style used in the
    first edition of The C Programming Language, by Kernighan
    and Ritchie].

    This is the proper formatting style with braces

    if (failed)
    {
    ...
    }
    else
    {
    ...
    }

    The vertical spacing introduced by the `{` line provides
    separation between condition and the branch, which makes
    your code much more readable. [...]

    What qualities does this layout style have that make it "more
    readable", other than it being one that you like or prefer?

    Er... The answer to his question is already present in the quoted
    portion of my post. "The vertical spacing introduced..."

    Does that mean you think this

    if (failed) {

    ...

    } else {

    ...

    }

    is just as readable? Or is it something besides the
    vertical spacing that bears on your "more readable"
    judgment?

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Michael S@21:1/5 to Tim Rentsch on Sun Sep 29 12:48:35 2024
    On Sat, 28 Sep 2024 21:53:06 -0700
    Tim Rentsch <[email protected]> wrote:

    Michael S <[email protected]> writes:

    On Sat, 28 Sep 2024 05:02:05 -0700
    Tim Rentsch <[email protected]> wrote:

    Andrey Tarasevich <[email protected]> writes:

    [...]

    And don't use "Egyptian" braces [the style used in the
    first edition of The C Programming Language, by Kernighan
    and Ritchie].

    This is the proper formatting style with braces

    if (failed)
    {
    ...
    }
    else
    {
    ...
    }

    The vertical spacing introduced by the `{` line provides
    separation between condition and the branch, which makes
    your code much more readable. [...]

    What qualities does this layout style have that make it "more
    readable", other than it being one that you like or prefer?

    { at the same level of indentation as its matching }

    Certainly it is true that the layout style shown has the open
    brace at the same level of indentation as the matching close
    brace. What about that property makes this layout "more
    readable"? The statement given sounds like a tautology -
    I don't see that any new information has been added.

    It makes it easier to see where block starts and where it ends. Opening
    { followed by empty line is more bold visually than 'if something { ' or
    then '} else {'.

    Now, I can live with both styles, but can see why many people prefer
    style advocated by Andrey.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Andrey Tarasevich@21:1/5 to Tim Rentsch on Sun Sep 29 07:41:14 2024
    On 09/28/24 10:47 PM, Tim Rentsch wrote:
    efer?

    Er... The answer to his question is already present in the quoted
    portion of my post. "The vertical spacing introduced..."

    Does that mean you think this

    if (failed) {

    ...

    } else {

    ...

    }

    is just as readable? Or is it something besides the
    vertical spacing that bears on your "more readable"
    judgment?

    No, the spacing in question is the spacing between the `if` condition
    and the first line of the the first compound statement.

    This is unreadable and unacceptable

    if (condition) {
    whatever1; /* <-- Bad! No vertical separation! */
    whatever2;
    }

    for (abc; def; ghi) {
    whatever1; /* <-- Bad! No vertical separation! */
    whatever2;
    }

    This is _immensely_ more readable

    if (condition)
    { /* <-- Good! Vertical space */
    whatever1;
    whatever2;
    }

    for (abc; def; fgh)
    { /* <-- Good! Vertical space */
    whatever1;
    whatever2;
    }

    This readability problem exists one the other end with struct
    declarations and `do{}while` syntax as well

    typedef struct MyStruct
    {
    int a;
    double b;
    char c;
    } MyStruct; /* <-- Bad! No vertical separation! */

    do
    {
    whatever1;
    whatever2;
    } while (condition); /* <-- Bad! No vertical separation! */

    I don't have a perfect solution for this variation of the same issue.
    So, I tend to use

    typedef struct MyStruct
    {
    int a;
    double b;
    char c;

    } MyStruct;

    do
    {
    whatever1;
    whatever2;

    } while (condition);

    although admittedly this has its own drawbacks.

    --
    Best regards,
    Andrey

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Michael S@21:1/5 to Andrey Tarasevich on Sun Sep 29 18:04:31 2024
    On Sun, 29 Sep 2024 07:41:14 -0700
    Andrey Tarasevich <[email protected]> wrote:

    On 09/28/24 10:47 PM, Tim Rentsch wrote:
    efer?

    Er... The answer to his question is already present in the quoted
    portion of my post. "The vertical spacing introduced..."

    Does that mean you think this

    if (failed) {

    ...

    } else {

    ...

    }

    is just as readable? Or is it something besides the
    vertical spacing that bears on your "more readable"
    judgment?

    No, the spacing in question is the spacing between the `if` condition
    and the first line of the the first compound statement.

    This is unreadable and unacceptable

    if (condition) {
    whatever1; /* <-- Bad! No vertical separation! */
    whatever2;
    }

    for (abc; def; ghi) {
    whatever1; /* <-- Bad! No vertical separation! */
    whatever2;
    }

    This is _immensely_ more readable

    if (condition)
    { /* <-- Good! Vertical space */
    whatever1;
    whatever2;
    }

    for (abc; def; fgh)
    { /* <-- Good! Vertical space */
    whatever1;
    whatever2;
    }


    It seems, you didn't understand the question.
    Tim was asking about your opining w.r.t.
    if (condition) {

    whatever1;
    whatever2;
    }

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Scott Lurndal@21:1/5 to Andrey Tarasevich on Sun Sep 29 18:30:30 2024
    Andrey Tarasevich <[email protected]> writes:
    On 09/28/24 10:47 PM, Tim Rentsch wrote:
    efer?

    Er... The answer to his question is already present in the quoted
    portion of my post. "The vertical spacing introduced..."

    Does that mean you think this

    if (failed) {

    ...

    } else {

    ...

    }

    is just as readable? Or is it something besides the
    vertical spacing that bears on your "more readable"
    judgment?

    No, the spacing in question is the spacing between the `if` condition
    and the first line of the the first compound statement.

    This is unreadable and unacceptable

    if (condition) {
    whatever1; /* <-- Bad! No vertical separation! */
    whatever2;
    }

    for (abc; def; ghi) {
    whatever1; /* <-- Bad! No vertical separation! */
    whatever2;
    }

    This is _immensely_ more readable

    To you. I find it less readable than the above.

    For those of us who started with ed/vi, certain paradigms
    evolved - such as ensuring the function name for a function
    definition starts in column 1 so you can easily find it
    using /^function-name, so

    int
    main(...)
    {
    }

    is preferrred over

    int main(...) {
    }


    Likewise, the opening brace for the function should start
    a line (supporting the '[[' and ']]' vim commands).

    (and '%' use useful to match braces).

    Indentation should be a sufficient visual cue without wasting
    whitespace on useless blank lines.

    f = fdopen(fd, "r");
    if (f == NULL) {
    lp->log("Unexpected error re-opening '%s': %s\n",
    filename, strerror(errno));
    close(fd);
    goto done;
    }

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Tim Rentsch@21:1/5 to Andrey Tarasevich on Sun Sep 29 18:39:06 2024
    Andrey Tarasevich <[email protected]> writes:

    On 09/28/24 10:47 PM, Tim Rentsch wrote:
    efer?

    Er... The answer to his question is already present in the quoted
    portion of my post. "The vertical spacing introduced..."

    Does that mean you think this

    if (failed) {
    ...
    } else {

    ...

    }

    is just as readable? Or is it something besides the
    vertical spacing that bears on your "more readable"
    judgment?

    No, the spacing in question is the spacing between the `if`
    condition and the first line of the the first compound statement.

    My question was misquoted. I was asking about this:

    if (failed) {

    ...

    } else {

    ...

    }

    where there is a blank line after the "if()" line, both before
    and after the "} else {" line, and before the line with the final
    closing brace.

    This layout has as much vertical separation as the layout style
    you prefer (and one more blank line at the end). Do you think it
    is just as readable as your preferred layout? Or is it something
    besides the vertical spacing that bears on your "more readable"
    judgment?

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Kaz Kylheku@21:1/5 to Andrey Tarasevich on Mon Sep 30 02:03:20 2024
    On 2024-09-29, Andrey Tarasevich <[email protected]> wrote:
    On 09/28/24 10:47 PM, Tim Rentsch wrote:
    efer?

    Er... The answer to his question is already present in the quoted
    portion of my post. "The vertical spacing introduced..."

    Does that mean you think this

    if (failed) {

    ...

    } else {

    ...

    }

    is just as readable? Or is it something besides the
    vertical spacing that bears on your "more readable"
    judgment?

    No, the spacing in question is the spacing between the `if` condition
    and the first line of the the first compound statement.

    This is unreadable and unacceptable

    if (condition) {
    whatever1; /* <-- Bad! No vertical separation! */
    whatever2;
    }

    for (abc; def; ghi) {
    whatever1; /* <-- Bad! No vertical separation! */
    whatever2;
    }

    This is _immensely_ more readable

    if (condition)
    { /* <-- Good! Vertical space */
    whatever1;
    whatever2;
    }

    for (abc; def; fgh)
    { /* <-- Good! Vertical space */
    whatever1;
    whatever2;
    }

    I don't see a readability difference. I'm not a kook.

    Both examples use correct indentation.

    The braces are placed such that the indentation does not lie.

    If that is the case, you don't have to care how exactly they
    are placed.

    When I look at this code, my brain mostly sees it like this:

    if (condition)
    whatever1; /* <-- Bad! No vertical separation! */
    whatever2;

    for (abc; def; ghi)
    whatever1; /* <-- Bad! No vertical separation! */
    whatever2;

    if (condition)
    /* <-- Good! Vertical space */
    whatever1;
    whatever2;


    for (abc; def; fgh)
    /* <-- Good! Vertical space */
    whatever1;
    whatever2;

    except that if there is something deceptive with the braces going on,
    there is a good chance my brain will still alert me to it.

    "Cuddled braces" is a very popular formatting style; it behooves you to
    get used to it.

    This readability problem exists one the other end with struct
    declarations and `do{}while` syntax as well

    typedef struct MyStruct
    {
    int a;
    double b;
    char c;
    } MyStruct; /* <-- Bad! No vertical separation! */

    do
    {
    whatever1;
    whatever2;
    } while (condition); /* <-- Bad! No vertical separation! */

    I don't have a perfect solution for this variation of the same issue.
    So, I tend to use

    I don't understand what would be wrong with:

    do
    {
    whatever1;
    whatever2;
    }
    while (condition); /* <-- Good! Vertical separation! */

    For the typedef you can always do this:

    typedef struct MyStruct MyStruct;

    struct MyStruct
    {
    int a;
    double b;
    char c;
    };

    --
    TXR Programming Language: http://nongnu.org/txr
    Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal
    Mastodon: @[email protected]

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Kaz Kylheku@21:1/5 to Keith Thompson on Mon Sep 30 02:29:10 2024
    On 2024-09-29, Keith Thompson <[email protected]> wrote:
    Andrey Tarasevich <[email protected]> writes:
    [...]
    This is unreadable and unacceptable

    if (condition) {
    whatever1; /* <-- Bad! No vertical separation! */
    whatever2;
    }

    for (abc; def; ghi) {
    whatever1; /* <-- Bad! No vertical separation! */
    whatever2;
    }

    This is _immensely_ more readable

    if (condition)
    { /* <-- Good! Vertical space */
    whatever1;
    whatever2;
    }

    for (abc; def; fgh)
    { /* <-- Good! Vertical space */
    whatever1;
    whatever2;
    }
    [...]

    Andrey, I hope you're aware that you're stating your own personal
    preferences as if they were incontrovertible fact.

    Readability is a combination of the text being read and the person
    reading it. I accept without question that *you* find K&R-style
    brace placement "unreadable and unacceptable". A lot of experienced
    C programmers, myself included, either prefer the K&R style or
    find both styles more or less equally readable. And many prefer
    vertically aligned braces but can deal with K&R-style braces.

    For what it may be worth, the K&R style is pretty much baked into the
    Awk language. These two Awk programs are not equivalent:

    /foo/
    {
    foo++
    }

    vs:

    /foo/ {
    foo++
    }

    The first one will print every record which contains a match
    for the regular expression foo, and count every record.

    The second will increment foo for every record that matches foo.

    It is an undeniable fact that alignment and grouping is important
    in visual design, and that use of these elements (and others)
    is important in creating signs and displays that are easy to
    grok at a glance.

    Aligning opening and closing punctuators in programming is going
    overboard though.

    Here is why: we have already decided that these punctuators are
    not helpful in helping us grok the structure of the code, and
    instead rely on indentation.

    The reason that the punctuators are not helpful is not because they are
    not vertically aligned.

    However, if we take away indentation from all the code other
    than the braces, then the vertical alignment does help recover
    some of the lost readability:

    Compare:

    if (condition) {
    for (abc; def; fgh) {
    if (nested-condition) {
    whatever1;
    whatever2;
    }
    }
    } else {
    whatever3;
    }

    versus:

    if (condition)
    {
    for (abc; def; fgh)
    {
    if (nested-condition)
    {
    whatever1;
    whatever2;
    }
    }
    }
    else
    {
    whatever3;
    }

    But the likely reason for this is that the aligned braces increase the
    amount of correct indentation. The structural cue from indentation is
    only coming from the braces here, so if half of them are not indented,
    then half that signal is gone.

    I can sort of see why this identation signal from the opening braces
    would be important even if the code were fully indented, to someone who
    has some sort of cognitive quirk.

    Also, I can see how the structure is more nicely conveyed when the
    eopening braces are indented, if the reader temporarily blocks out
    the visibility of the code and focuses on only seeing the braces:

    This:

    {

    {

    {


    }
    }
    }

    {

    }

    versus:

    {
    {
    {


    }
    }
    } {

    }

    In other words, the vertical braces enable a mode of visually filtering
    the code that may be of use to some. (Though, to me, choosing to see
    the braces while suppressing the rest of the code seems wrongheaded. Or wrong-eyed?)

    It is mainly an indentation signal though; the main aspect is not the
    vertical alignment, but the correct indentation nesting. All the
    matching braces are still vertically aligned in this code also, yet
    the indentation is haphazard and unhelpful:

    if (condition)
    {
    for (abc; def; fgh)
    {
    if (nested-condition)
    {
    whatever1;
    whatever2;
    }
    }
    }
    else
    {
    whatever3;
    }

    --
    TXR Programming Language: http://nongnu.org/txr
    Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal
    Mastodon: @[email protected]

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Tim Rentsch@21:1/5 to Michael S on Sun Sep 29 19:18:54 2024
    Michael S <[email protected]> writes:

    On Sat, 28 Sep 2024 21:53:06 -0700
    Tim Rentsch <[email protected]> wrote:

    Michael S <[email protected]> writes:

    On Sat, 28 Sep 2024 05:02:05 -0700
    Tim Rentsch <[email protected]> wrote:

    Andrey Tarasevich <[email protected]> writes:

    [...]

    And don't use "Egyptian" braces [the style used in the
    first edition of The C Programming Language, by Kernighan
    and Ritchie].

    This is the proper formatting style with braces

    if (failed)
    {
    ...
    }
    else
    {
    ...
    }

    The vertical spacing introduced by the `{` line provides
    separation between condition and the branch, which makes
    your code much more readable. [...]

    What qualities does this layout style have that make it "more
    readable", other than it being one that you like or prefer?

    { at the same level of indentation as its matching }

    Certainly it is true that the layout style shown has the open
    brace at the same level of indentation as the matching close
    brace. What about that property makes this layout "more
    readable"? The statement given sounds like a tautology -
    I don't see that any new information has been added.

    It makes it easier to see where block starts and where it ends.
    Opening { followed by empty line is more bold visually than 'if
    something { ' or then '} else {'.

    Certainly having an open brace on a line by itself stands out
    more than if the open brace were written at the end of an if()
    or while() line.

    Whether that makes it easier to see where a block starts is
    something that can be measured, and also might be reader
    dependent. For myself I find that having open braces on lines by
    themselves interferes with my ease of reading. And that has been
    true since before I ever programmed in C.

    Now, I can live with both styles, but can see why many people
    prefer style advocated by Andrey.

    I've made a serious effort over the years to find out why people
    who prefer the Andrey style are so definite that it is somehow
    better. I have yet to get an illuminating answer to that
    question. I've gotten various forms of non-answer arguments, and
    what seem to me to be circular answers (like saying it is more
    readable). I understand that they prefer it; I still don't
    understand why they prefer it. I acknowledge your point that
    they think the open brace on a line by itself somehow helps with
    their reading. But I still don't understand why they think that.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Janis Papanagnou@21:1/5 to Kaz Kylheku on Mon Sep 30 11:26:31 2024
    First, I want to re-emphasize that valuation of styles lies in the
    eye of the beholder. Then, for practical purposes, there's usually (coding-)standards defined [in professional contexts] that define
    the rules folks have to follow. While in private contexts everyone
    is free to follow own personal preferences.

    On 30.09.2024 04:29, Kaz Kylheku wrote:
    [...]

    For what it may be worth, the K&R style is pretty much baked into the
    Awk language. These two Awk programs are not equivalent:

    /foo/
    {
    foo++
    }

    vs:

    /foo/ {
    foo++
    }

    For the readers unfamiliar with Awk it should be mentioned that
    this is a consequence of Awk's implicit defaults.

    /foo/ is equivalent to /foo/ { print $0 }

    and

    { foo++ } is equivalent to 'true' { foo++ }

    (using the informal 'true' as placeholder for any true condition).

    Thus you have to put the opening braces on the same line as the
    condition to indicate that condition and action belong together.

    [...]

    It is an undeniable fact that alignment and grouping is important
    in visual design, and that use of these elements (and others)
    is important in creating signs and displays that are easy to
    grok at a glance.

    Sic!

    [...]

    Also, I can see how the structure is more nicely conveyed when the
    eopening braces are indented, if the reader temporarily blocks out
    the visibility of the code and focuses on only seeing the braces:

    This:

    {

    {

    {


    }
    }
    }

    {

    }

    As far as I'm concerned, it's not only the braces but also the
    placement of the associated control-structure keywords that
    matters.

    To _quickly_ *assert* the code structure the following...


    versus:

    {
    {
    {


    }
    }
    } {

    }

    ...is indeed [unnecessarily] suboptimal! (And adding the keywords
    doesn't make that situation better.) Having tool support (like
    an editor's syntax highlighting) might alleviate that issue (but
    does not solve it).

    (Maybe it's to some degree comparable with the difference between
    ragged layout of texts vs. text that has consistent line lengths
    or is even block-justified.)


    In other words, the vertical braces enable a mode of visually filtering
    the code that may be of use to some. (Though, to me, choosing to see
    the braces while suppressing the rest of the code seems wrongheaded. Or wrong-eyed?)

    There's nothing suppressed. (Moreover I think any tries to value
    other preferences with psychological assumptions and personal
    valuations doesn't serve the discussions.)

    BTW, a friend of mine (a long year experienced CS professional)
    prefers [to my astonishment] a formatting I've not (or certainly
    not widely) seen before...

    while (cond)
    {
    stmt1;
    stmt2;
    }

    Also aligned (but differently).

    [...]

    It might make sense - besides visual or "psychological" explanations -
    to also include people's experiences with or influences from other
    programming languages they use. People may be used to structures like

    if condition then
    begin
    ...
    end
    else
    ...

    which can be found in many languages (Algol, Pascal, ...), or from
    the Unix [standard] shell where syntax requirements foster structures
    like

    if command1
    then
    command2
    else
    command3
    fi


    My personal preferences are best supported by a syntax that you
    find in Algol 68, Eiffel (or Unix shell), where you usually don't
    need any sort of brackets in control structures, and where there's
    thus less dispute about where to place the 'opening block' symbol.

    Janis

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From David Brown@21:1/5 to Andrey Tarasevich on Mon Sep 30 13:17:45 2024
    On 29/09/2024 16:41, Andrey Tarasevich wrote:
    On 09/28/24 10:47 PM, Tim Rentsch wrote:
    efer?

    Er... The answer to his question is already present in the quoted
    portion of my post.  "The vertical spacing introduced..."

    Does that mean you think this

         if (failed) {
           ...
         } else {

           ...

         }

    is just as readable?  Or is it something besides the
    vertical spacing that bears on your "more readable"
    judgment?

    No, the spacing in question is the spacing between the `if` condition
    and the first line of the the first compound statement.

    This is unreadable and unacceptable


    I hope you are aware that that is, at best, a personal opinion? Given
    that a great many C programmers write code that way and find it both
    readable and acceptable - indeed preferable to your own style - your
    claim is obviously factually incorrect.

    If you can provide evidence in the form of studies or statistical data
    that demonstrate that your style is significantly easier to read for
    many people, or leads to fewer errors in code, then I think many people
    here would be interested in that. But as it stands, your post is as
    useful as telling us that the best flavour of ice-cream is obviously
    strawberry and that chocolate ice-cream is inedible.


    This readability problem exists one the other end with struct
    declarations and `do{}while` syntax as well


    I don't have a perfect solution for this variation of the same issue.
    So, I tend to use

      typedef struct MyStruct
      {
        int a;
        double b;
        char c;

      } MyStruct;

      do
      {
        whatever1;
        whatever2;

      } while (condition);

    although admittedly this has its own drawbacks.


    Note that the "one true brace" style has no problem here and is
    consistent in these cases. Consistency is not necessarily of overriding importance, but it often helps readability.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Alan Mackenzie@21:1/5 to Michael S on Mon Sep 30 15:05:39 2024
    Michael S <[email protected]> wrote:
    On Sat, 28 Sep 2024 21:53:06 -0700
    Tim Rentsch <[email protected]> wrote:

    Michael S <[email protected]> writes:

    On Sat, 28 Sep 2024 05:02:05 -0700
    Tim Rentsch <[email protected]> wrote:

    Andrey Tarasevich <[email protected]> writes:

    [...]

    And don't use "Egyptian" braces [the style used in the
    first edition of The C Programming Language, by Kernighan
    and Ritchie].

    This is the proper formatting style with braces

    if (failed)
    {
    ...
    }
    else
    {
    ...
    }

    The vertical spacing introduced by the `{` line provides
    separation between condition and the branch, which makes
    your code much more readable. [...]

    What qualities does this layout style have that make it "more
    readable", other than it being one that you like or prefer?

    { at the same level of indentation as its matching }

    Certainly it is true that the layout style shown has the open
    brace at the same level of indentation as the matching close
    brace. What about that property makes this layout "more
    readable"? The statement given sounds like a tautology -
    I don't see that any new information has been added.

    It makes it easier to see where block starts and where it ends. Opening
    { followed by empty line is more bold visually than 'if something { ' or
    then '} else {'.

    Now, I can live with both styles, but can see why many people prefer
    style advocated by Andrey.

    I think it objectively true that superfluous compound statements and
    opening braces on lines of their own make code less readable. Not by a
    lot, but by enough.

    The reason is that people are not struggling to read individual
    statements (apart from raw beginners), they are struggling to read a
    whole program. With the lots-of-blank-lines styles advocated by some,
    less of a program will fit on a screen than with more economical styles.
    That means more scrolling up and down to see what should be closely
    related parts of the program.

    This is more true of modern IDEs, where only a small part of the screen
    is devoted to the program text, than good text editors. For example, in
    Emacs (using Follow Mode) I can get 195 consecutive lines displayed
    legibly and usably on my screen at once. But even with that, having superfluous vertical space occasionally makes me have to scroll.

    At a high level of abstraction, what makes code difficult to understand
    and debug is having to look somewhere else. The
    superfluous-vertical-space styles increase that difficulty, if only a
    little.

    --
    Alan Mackenzie (Nuremberg, Germany).

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Tim Rentsch@21:1/5 to Andrey Tarasevich on Fri Sep 27 01:43:34 2024
    Andrey Tarasevich <[email protected]> writes:

    On 09/24/24 7:36 AM, Tim Rentsch wrote:

    My long-standing habit is to write this

    if(x) bar(x);

    or this

    if(x){
    bar(x);
    }

    but never this

    if(x)
    bar(x);

    The reason for this habit is that many years ago I got bitten by
    trying to add a line in the last case. The habit subsequently
    adopted has proven very effective at eliminating such errors.

    It is just weird.

    This is no different from insisting in using "Yoda conditions",
    claiming that "many years ago I was bitten by an accidental =
    in place of ==".

    Don't be silly, of course they are different. There is nothing
    artificial about surrounding controlled statements with braces.
    And writing braceless single-line if()s in cases where there
    is only a single controlled statement is something I was already
    doing - I didn't adopt it as a reaction to something that
    happened with multi-line if()s.

    In reality we all know that regardless of how many scary
    stories someone might tell about dangers of accidental
    assignment in place of comparison, it just does not happen.
    There's no such issue. People just don't make this mistake.

    Your view is contradicted by objective reality.

    The same applies to

    if(x)
    bar(x);

    This is the right thing to do. It is the most readable and
    elegant way to write a simple `if`.

    I think you need to learn the difference between a statement
    of opinion and a statement of fact.

    And the dreaded "one day you will add a line and suffer" just
    doesn't happen. There's no such issue. People just don't make
    this mistake.

    Making a false statement twice doesn't make it true.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Tim Rentsch@21:1/5 to Andrey Tarasevich on Fri Sep 27 03:38:27 2024
    Andrey Tarasevich <[email protected]> writes:

    On 09/21/24 2:54 PM, Keith Thompson wrote:

    [...]

    What you call "Egyptian" braces is the style used by the creators
    of the language

    Firstly, this is style. Being a "creator of the language" does not
    make one an authority on code formatting style.

    Secondly, most people pick up "the style used by the creators of
    the language" from the code samples used in the 2nd edition of K&R
    book. And, as we know, "the creators of the language" went a
    little lazy here. The samples were considered of "low importance"
    and fell victim to the tightening publishing schedules in front of
    the looming "threat" of the upcoming ANSI standard. The code
    samples were never properly updated to match the style and spirit
    of modern C.

    Your reasoning is rife with errors of logic and facts not in
    evidence.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)