Join the discussion
Write your take first — we'll ask for email only when you're ready to publish.
- Hacker News
- > the implementation may assume any thread will eventually do one of the following: terminate, call a library I/O function, access a volatile glvalue, or perform a synchronization or atomic operation
Why is that rule needed? I could make my for loop try to solve the halting problem and it'll never finish either, circumventing that rule
by Aardwolf - > [The C rule was rejected for C++ because it] could inhibit useful optimizations
If be curious if these are the sorts of optimizations I would find useful to the point where I would be happy to pay the price of this annoying new behaviour.
Or are they just the sorts of optimizations that a compiler writer finds useful who is engaged in a multi year career-defining pissing contest with a competing team?
Don't get me wrong, I have myself engaged in a multi year career-defining pissing contest with a competing team. It's fun. But let's not kid ourselves that it's for the users' sake.
by ErikCorry - I don't see how it can be useful. It's almost always an error to write such a loop. The only reason for it to exist is in very low-level code to do nothing, but for such cases using something like an external function written in assembly is perfectly fine, no C++ standard changes are necessary. It's even makes things harder by complicating the standard with little to no benefits in exchange.by Panzerschrek
- There are valid use cases for the infinite while(1) loop in microcontroller programming (contrary to popular belief it seems). Autogenerated HAL code for the stm32 uses it for error handlers, and they support C++ so I am surprised this was UB.
I only use it for error handling and of course it is a bad idea to use this to wait/stall in power sensitive applications, in that case use wake from interrupt.
As an aside, I like to include a software breakpoint in my error handlers. It makes debugging easier without wasting a hardware breakpoint (which are physically limited by the microcontroller):
__BKPT(); while (1) ;by peterus - The article, most unfortunately, doesn't explain why anyone would want infinite loops to be UB in the first place. I found this explanation: https://www.open-std.org/jtc1/sc22/wg14/www/docs/n1528.htm
- > The loop must be a trivially empty iteration statement -- meaning its body is literally empty
This seems to say that the loop body can not be "continue". Indeed, I just tried -std=c++26 with ";" and got an infinite loop as promised, but "continue" restores the undefined behavior:
- "while(true);" -> https://godbolt.org/z/T65o51crx
- "while(true) continue;" -> https://godbolt.org/z/Pj9raEcnP
This is unfortunate since I know of one style guide that prefers "continue" over single semicolons. I guess all those code will be doing "while(true) {}" from now on.
https://google.github.io/styleguide/cppguide.html#Formatting...
by omoikane - > 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.
by JoshTriplett - > 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.
by wahern