Is infinite loop still undefined behavior in C++ if it calls shared library?

It's said that infinite loop for(;;); is undefined behavior.


From http://en.cppreference.com/w/cpp/language/memory_model

In a valid C++ program, every thread eventually does one of the following:

  • terminate
  • makes a call to an I/O library function
  • reads or modifies a volatile object
  • performs an atomic operation or a synchronization operation

No thread of execution can execute forever without performing any of these observable behaviors.

Note that it means that a program with endless recursion or endless loop (whether implemented as a for-statement or by looping goto or otherwise) has undefined behavior.


But what if it calls a function in shared library?

for(;;) sofunc();

The function could do any kind of blocking I/O, or throw exception.

In this case, does the compiler assume that the loop has some observable behaviors?


There are a number of places where the language of the Standard gives compilers freedoms beyond what are required for useful optimizations, but which would instead provide compilers with ways to throw the Principle of Least Astonishment out the window. The way the rules about endless loops are written fits that category.

Most of the optimizations which would be facilitated by the rules about endless loops would be enabled by language which specified that the time required to execute a section of code, even if infinite, is not considered to be a side-effect that compilers are required to preserve. Such a rule would allow a compiler to omit any loop iterations which don't have any direct side-effects and don't modify values that are used elsewhere.

The Standard, however, goes beyond that. Given the code:

int foo(void)
{
  int x=0;
  do
  {
    x=functionWithNoSideEffects(x);
  } while(x != 23 && x != 42);
  return x;
}

a compiler that could show that functionWithNoSideEffects would never have any defined side-effects and would never return 23 could replace the code for "foo" with "return 42;". Even if the purpose of the program was to test whether functionWithNoSideEffects would ever return 42 (in which case having the generated code return 42 whether the function does or not would be unhelpful) the Standard would not require compilers to generate code to actually test that unless the loop included some kind of "side-effect".

I'm not personally convinced that the value of having a rule that says that if compilers can show that a loop can't terminate without X being true, they may regard X as being true whether or not there's any means by which it could be. Optimizations based on that principle seem popular, however.