In the situation you've provided, inlining provides no additional problems above and beyond the normal problems of accessing data without locks of some sort. It isn't as if inlining getDone()
to just done
somehow erases the properties of done
into being non-static or something. Like if you coded done
in directly as in the example code, there's a risk of an infinite loop, but that'd be true irrespective of inlining or not because cpp's specification leaves this sort of unprotected multi-threaded access to a variable as (I believe) undefined behavior so you might have an infinite loop, you might have a loop that eventually stops if a different thread updates done
, and you might have a loop that ~immediately stops if a different thread updates done
as if it were protected. Weird things happen in undefined behavior, so there's no easy way to answer what you've asked (AFAIK, I haven't made a thorough investigation of the C++11 spec on this particular point).
Properly implemented inlining doesn't change what is being executed in an unsafe manner because that's sort of the definition of a correct inline. If inlining a method altered its behavior such that it stopped working in a multi-threaded environment, that would be a bug in the compiler that would need to be fixed.
There is, of course, a lot of room for error in compilers and such a bug may very well exist. In practice, an inlining compiler detects situations where inlining might cause a problem and either avoids inlining or fixes the problem. For the most part, inlining is safe and the reason you don't inline is because of ambiguity over what code to inline (in case there's overloading/inheritance/virtual calls going on), recursion (you can't inline a function into itself infinitely, but you can up to a limit), or performance considerations (typically increased code size, but also causing code blocks to become so large that other optimizations are disabled).