C++ Logo


Advanced search

Re: Remove infinite loop UB

From: Andrey Semashev <andrey.semashev_at_[hidden]>
Date: Sat, 9 May 2020 12:04:40 +0300
On 2020-05-09 04:02, connor horman via Std-Proposals wrote:
> Currently in the C++ language, it is undefined behaviour to have an
> infinite loop without observable side effects. 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).

yield() is potentially observable because it may result in execution of
a thread that has observable behavior.

> 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.

I don't believe you really are spinning forever, as that would be a
rather useless program. Every time you say you're spinning *waiting for
something*, you already have a termination condition - it's when that
something happens. You may have phrased that weirdly in the code, which
makes it look like an infinite loop, but you should be able to do it the
right way.

For example, if you're waiting for an interrupt, then in terms of your
program you must be waiting until a std::sig_atomic_t variable becomes
true, and set that variable to true in the signal handler.

Received on 2020-05-09 04:07:45