C++ Logo

liaison

Advanced search

Re: [wg14/wg21 liaison] [isocpp-parallel] Proposal: Trivial infinite loops are not Undefined Behavior

From: Hans Boehm <boehm_at_[hidden]>
Date: Fri, 17 Feb 2023 09:05:05 -0800
I agree.
It's also interesting that clang doesn't seem to literally implement the
rule from the C standard. I also get different behavior for

#include <stdio.h>

int main() {
    int x = 1;
    while (x);
}

void unreachable() {
    puts("Hello world!");
}

which I believe is UB in both standards.

And I see the same difference for a goto loop. That might make more sense;
the C++ progress guarantee probably allows that, and Olivier's argument
requires that to be UB.

On Fri, Feb 17, 2023 at 8:50 AM Tom Honermann via Liaison <
liaison_at_[hidden]> wrote:

> My guess is that this is the result of two optimization passes. One
> concludes that code following the while is not reachable and eliminates
> code for the implicit return. The other determines that the while loop
> has no effect and eliminates it. The end result is that a symbol for
> main is emitted, but no code is. When main is called, whatever happens
> to follow it in memory ends up running. Different behavior is observed
> if the definition of unreachable is moved above main.
> https://godbolt.org/z/beeaT591r.
>
> Tom.
>
> On 2/17/23 4:51 AM, Aaron Peter Bachmann via Liaison wrote:
> > Hello Robert!
> > I understand the while(1)-loop can be assumed to terminate.
> > But who calls unreachable()? It is not in the body of main().
> > I would expect main() to return with 0 for C and an unspecified value
> > for C++
> > or alternatively remain in the endless loop for both languages.
> >
> > Regards, Aaron Peter Bachmann
> >
> > On 2/16/23 05:42, Robert Seacord via Liaison wrote:
> >> I'm not sure if someone has posted this example yet, but here is a
> >> fun example that compiles in both C and C++ with different results:
> >>
> >> #include <stdio.h>
> >>
> >> int main() {
> >> while (1)
> >> ;
> >> }
> >>
> >> void unreachable() {
> >> puts("Hello world!");
> >> }
> >>
> >> If you want to try it: https://godbolt.org/z/1d3hzseh4
> >>
> >> In C, this code produces an infinite loop while in C++ it does the
> >> following:
> >>
> >> image.png
> >>
> >> On Wed, Feb 15, 2023 at 11:31 PM Robert Seacord <rcseacord_at_[hidden]>
> >> wrote:
> >>
> >> Hans,
> >>
> >> I initiated this latest discussion on the WG14 reflector and I've
> >> recently become a bit more active in WG21 (and my boss is JF who
> >> wrote this paper).
> >>
> >> Here is a recap of some of the history of this issue:
> >>
> >> I can't find any forward progress guarantee in the C Standard.
> >> The word "progress" does not appear anywhere in the standard.
> >> Subclause 6.8.5, "Iteration statements" paragraph 5 says:
> >>
> >> An iteration statement may be assumed by the implementation to
> >> terminate if its controlling
> >> expression is not a constant expression197), and none of the
> >> following operations are performed in its
> >> body, controlling expression or (in the case of a for statement)
> >> its expression-3198):
> >> — input/output operations
> >> — accessing a volatile object
> >> — synchronization or atomic operations.
> >>
> >> 197) An omitted controlling expression is replaced by a nonzero
> >> constant, which is a constant expression.
> >> 198) This is intended to allow compiler transformations such as
> >> removal of empty loops even when termination cannot be
> >> proven.
> >>
> >> N1509 proposes to eliminate 6.8.5p6 in the current WP as the
> >> author believes it to be incompatible with C99. See also N1528,
> >> Item 6.30, Response to N1509.
> >>
> >> N1528 covers why the rules were added. N1509 was written to show
> >> a compiler can determine the opposite as well.
> >> In https://open-std.org/jtc1/sc22/wg14/www/docs/n1509.pdf [Walls]
> >> contends that many C90/C99 programs rely on entrance to an
> >> unending loop to proceed no further (within that thread). Those
> >> programs are relying on the semantics of C99 6.8.5p4: "An
> >> iteration statement causes a statement called the loop body to be
> >> executed repeatedly until the controlling expression compares
> >> equal to 0."
> >>
> >> N1528 breaks existing conforming programs. Adding an exception may
> >> solve the intent of both papers. That approach should be run by
> >> Hans. We can defer a decision and not affect getting a CD out,
> >> then respond to an NB comment. We do want to be compatible with
> >> WG21.
> >>
> >> ACTION Douglas to work with Larry to come up with the proposed
> >> words are:
> >>
> >> Change 6.8.5p6 as follows:
> >> An iteration statement whose controlling expression is not a
> >> constant expression (or omitted), that performs no input/output
> >> operations, does not access volatile objects, and performs no
> >> synchronization or atomic operations in its body, controlling
> >> expression, or (in the case of a for
> >> statement) its expression, may be assumed by the implementation to
> >> terminate.
> >>
> >> Decision: Adopt N1509, as modified above, to the C1X WP. result:
> >> 14, 0, 1
> >>
> >> On Wed, Feb 15, 2023 at 8:29 PM Hans Boehm via Parallel
> >> <parallel_at_[hidden]> wrote:
> >>
> >> I read the current C wording, and the one proposed here, as
> >> saying that
> >>
> >> while(true) {
> >> if (!cond) break;
> >> ...
> >> }
> >>
> >> may not be assumed to terminate, and is thus very different from
> >>
> >> while(cond) {
> >> ...
> >> }
> >>
> >>
> >> This is a very confusing shorthand as "..." seems to imply any
> >> syntactically correct statements and thus the first pattern is a
> >> subset of the second pattern.
> >>
> >> I don't remember considering that before. This seems to be
> >> completely at odds with Olivier's goals. I also don't think
> >> this is a good idea, for purely loop optimization and
> >> understandability reasons. OTOH, some people on the WG14 list
> >> seem to think it is intentional and desired.
> >>
> >>
> >> Unlike what I said to JF at the meeting, it no longer sounds
> >> easy to me to remove this C vs. C++ divergence. There seem to
> >> be some substantive issues here.
> >>
> >>
> >> There is a strong desire in C to remain compatible with C++ and
> >> it's less clear what the C requirement is. There is a requirement
> >> that "while (1);" cannot be assumed to terminate as it is
> >> ubiquitous in environments where you don't have the luxury of
> >> calling exit() or yielding to the scheduler. I certainly wouldn't
> >> give up on compatibility at this point, and there is still a small
> >> window to change the C23 language as we are going to a second CD.
> >> Thanks,
> >> rCs
> >>
> >>
> >> _______________________________________________
> >> Liaison mailing list
> >> Liaison_at_[hidden]
> >> Subscription: https://lists.isocpp.org/mailman/listinfo.cgi/liaison
> >> Link to this post: http://lists.isocpp.org/liaison/2023/02/1175.php
> >
> >
> > _______________________________________________
> > Liaison mailing list
> > Liaison_at_[hidden]
> > Subscription: https://lists.isocpp.org/mailman/listinfo.cgi/liaison
> > Link to this post: http://lists.isocpp.org/liaison/2023/02/1178.php
> _______________________________________________
> Liaison mailing list
> Liaison_at_[hidden]
> Subscription: https://lists.isocpp.org/mailman/listinfo.cgi/liaison
> Link to this post: http://lists.isocpp.org/liaison/2023/02/1180.php
>

Received on 2023-02-17 17:05:17