‹ BackHN Continuity

Thread

C++26: Trivial infinite loops are no longer undefined behaviour

173 points · 290 comments · ibobev

  1. wahern · · focus · HN ↗
    > When both conditions are met, the loop body is replaced with a call to std::this_thread::yield(). This gives execution of the loop the forward-progress semantics it previously lacked.

    That's the epitome of the hidden code downside that Linus and many others dislike about C++. For constructors and destructors it's somewhat unavoidable and not so random, though Rust does better at limiting the blast radius of non-local code, at least in the drop case.

    If they didn't want to adopt the C11 rule, the C++ committee should've explored a rule that required the compiler to emit a diagnostic or error for trivial loops (whether as defined by C11 or otherwise), requiring the programmer to explicitly insert ::yield or similar. No hidden code, and less opportunity for the compiler to do surprising things.

    The C committee has been rigorously enumerating UB cases in the standard and addressing each case in turn, often by requiring a diagnostic, error, or by turning it into implemention defined behavior. But inserting code like that would be unthinkable.

    1. pbalau · · focus · HN ↗
      Is it hidden if it's explained in the standard?

      I think Linus's complain was before there was a c++ standard. An updated version of the complaint would be "this shit is doing too much".

      1. andrepd · · focus · HN ↗
        An empty loop, under some non-obvious conditions, on some compiler flags but not others, silently transforms into a system call. In a systems programming language.
        1. WalterBright · · focus · HN ↗
          I try to minimize use of destructors for the same reason.
          1. andrepd · · focus · HN ↗
            Destructors run predictably at list, and are pervasive everywhere. You know that when you exit a scope, be that a function or whatever it may, the destructors of variables in that scope are called. That is clear and consistent. The transformation mentioned above is not.
            1. WalterBright · · focus · HN ↗
              Understanding the code requires understanding the destructors of the objects you're using. Since they are invisibly inserted, they are a source difficulty in entirely understanding the code.
              1. rcxdude · · focus · HN ↗
                I do wonder if any of the language servers that insert implied type annotations would ever also show things like destructor calls in a similar manner. It seems like it would be quite useful.
Open on Hacker News to reply ↗

Unofficial Hacker News client; not affiliated with Y Combinator.