Currently in the C++ language, it is undefined behaviour to have an infinite loop without observable side effects.
Is that true? I thought the rule was that the compiler is allowed to assume that the loop will eventually terminate.
That would be the result of undefined behavior.
While this is nice on paper, it has a few issues. Any time you need to loop forever, you basically need to insert a (potentially costly) side effect. This applies any time you need are, say, running a game on a old console, and just need to spin while waiting for interrupts to do stuff (same with an os kernel). This results in requiring assembly to so this, or maybe insert an instruction to wait for an interrupt in a loop (both llvm and gcc allow the volatile specifier in an assembly declaration, which is treated as observable, so x86_64 code could use hlt (in CPL=0), 65816 could WAI). This, however, seems to violate one of C++'s core principles, that there is no lower level language.
A further case would be an init process on linux, which cannot terminate (doing so results in a kernel panic), nor can just call hlt in a loop, as that's one way to get a #GP which probably translates to SIGILL. Once an init process is done setting up, it could want to just spin forever, and do so using as little system resources as possible. The logical idea would be just for(;;) std::this_thread::yield();, but that would be UB as yield() is not observable (correct me if I'm wrong).
Having the ability to spin forever, without wasting time actually doing stuff, seems like a reasonable thing to have in low-level code, so its very curious (and in many cases, annoying) that you cannot actually do this in real code that might have to.
Couldn't you just do: `volatile int x; x = 0;`? This is considered a side effect.
That wastes time, especially in the init process example, where I really want to just spin forever. Time spent not yielding back to the kernel is time not available for another process that's next in the task queue (and there may not be a good alternative to spinning available, depending on os configuration. futexs may exist, or they may be disabled).
That may also cause issues with limited stack space (going back to my example with the 65816, I have 2k stack space, and interrupts doing whatever), Ideally, when I start spinning, I'm in the bottom stack frame, with no actual local variables allocated at the time, so it can just use the entire thing.
As a side note, not necessarily dealing with the specifics of the proposal, because of this "feature" llvm really likes to delete infinite loops that don't do anything, which leads to problems in other languages (particularly rust, where it is safe to use loop{}, an infinite loop, and rely on it being infinite, and the ability to cause undefined behaviour in safe code is a bug), and the same arguments apply there. Inserting a side effect has many of the same problems I bring up here.