‹ BackHN Continuity

Thread

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

173 points · 290 comments · ibobev

  1. JoshTriplett · · focus · HN ↗
    > When both conditions are met, the loop body is replaced with a call to std::this_thread::yield().

    Insert screaming here.

    An infinite loop, with no library calls whatsoever, gets a system call inserted. That's a horrible surprise waiting to happen.

    The entire concept of the "forward progress guarantee" is broken. An infinite loop should compile to an infinite loop. Nothing more, nothing less.

    1. saghm · · focus · HN ↗
      I guess given that it was UB before, the compiler was already allowed to put a system call here if it wanted for some reason
      1. chowells · · focus · HN ↗
        Not only that, the code was wrong. The specification is quite clear that correct programs don't cause UB to be executed at run time. If your wrong code now produces wrong results, that's because it's wrong. That your compiler allowed you to get away with it for decades is a compiler bug, not a feature.

        Do I fully believe all of the above? Not exactly. But compiler authors do. Does it make a really good argument to never use C or C++? Yes. If only we had 50 years of optimization work in any language with better semantics.

        1. saghm · · focus · HN ↗
          Yeah, my slightly more verbose take is that a language that requires you to not ever make any mistakes in order to have a program behave in a predictable way is not a particularly good choice of language if you the ability to pick something else.
        2. JoshTriplett · · focus · HN ↗
          The mistake was declaring infinite loops to be UB in the first place.
        3. throwaway786678 · · focus · HN ↗
          > That your compiler allowed you to get away with it for decades is a compiler bug

          That UB was added in C++11.

          1. chowells · · focus · HN ↗
            That sounds like 1.5 decades to me...
        4. TuxSH · · focus · HN ↗
          FWIW while(true) / for(;;) (or any other loop condition that is a true constant-expression) is NOT UB in C, only C++.

          In any case stuff like __asm__ __volatile__("" ::: "memory") prevent such optimizations in the rare case you do need branch-to-self.

        5. classified · · focus · HN ↗
          > don't cause UB to be executed at run time.

          The insidious thing about UB is that it doesn't necessarily have to be executed to wreck your program. UB is not primarily about runtime behavior, it's about how the compiler interprets your code. The behavior that is undefined is your compiler's behavior.

          1. chowells · · focus · HN ↗
            You're right. I didn't enumerate every way UB can make a program go wrong. I'm sure I don't even know every way that can happen. But "UB doesn't happen at run time" is an assumption that lots of "optimizations" are based on.
Open on Hacker News to reply ↗

Unofficial Hacker News client; not affiliated with Y Combinator.