0

Is this code defined behavior?

inline int a() { return 0 + a(); }

int main() { a(); }

If optimizations are enabled then Clang optimizes it out but GCC doesn't. So the code is not portable in practice. Does the C++ spec say anything about this?

StackedCrooked
  • 34,653
  • 44
  • 154
  • 278
  • 1
    The standard does discuss **implementation limits**, such as the maximally supported depth of recursion... The `inline` hint does not matter. If it's honored, then it's treated about the same as loop unrolling, with the compiler using its gut feeling as to how many expands it will do. – Cheers and hth. - Alf Apr 03 '14 at 12:03
  • To me, it's UB - bottomless recursion + depends on compiler's implementation (`inline` is just a _hint_ to the compiler). – Kiril Kirov Apr 03 '14 at 12:04
  • The function recursively calls itself on all control paths meaning you are guaranteed a runtime stack overflow. Ofcourse, it is up to the compiler to warn you of this. – Mo Beigi Apr 03 '14 at 12:08
  • 2
    @Mohammad: There's no such guarantee, as evidenced by the actual behaviour described in the question. – Lightness Races in Orbit Apr 03 '14 at 12:08
  • The code can be compiled and will never terminate. It is a recursive function and will continuously create function frames for each recursive call. I don't see why you aren't guaranteed a runtime stack overflow 'eventually'. – Mo Beigi Apr 03 '14 at 12:16
  • 1
    @Mohammad look up "C++ standard." –  Apr 03 '14 at 12:16
  • @rightfold Ah I was actually unaware that a stack overflow was 'undefined behavior'. Thanks for the clarification! – Mo Beigi Apr 03 '14 at 12:19
  • @Mohammad: Again, read the question. Also, read my answer. Also, click on the ideone.com link posted by David Kernin below my answer. Those are _demonstrations_ that what you are saying is false. – Lightness Races in Orbit Apr 03 '14 at 12:20
  • @Mohammad: You are not even guaranteed a stack overflow here. Please read what I am saying to you. – Lightness Races in Orbit Apr 03 '14 at 12:20
  • @Mohammad I never said it was. Stack overflows are pretty much irrelevant. Compilers may e.g. optimize out certain infinite loops. –  Apr 03 '14 at 12:21
  • @rightfold I see so the fact that it does not terminate implies that the program has 'undefined behavior'? – Mo Beigi Apr 03 '14 at 12:25

1 Answers1

3

As I discuss in this answer, regardless of the presence of the inline keyword, the behaviour of your code is certainly undefined since you call this function:

[C++11: 1.10/24]: The implementation may assume that any thread will eventually do one of the following:

  • terminate,
  • make a call to a library I/O function,
  • access or modify a volatile object, or
  • perform a synchronization operation or an atomic operation.

Clang is permitted to elide the entire thing, just as GCC is permitted to run it without inlining and reach a stack overflow. A compiler would also be free to attempt actual inlining, and it is even permitted to crash during compilation in such a case.

Crucially, there is no rule in the standard that makes the semantics for an infinite recursion differ just because a function is marked inline or even actually inlined ([C++11: 7.1.2]).

Of course, I reckon that if you were to never invoke this function, by the as-if rule a compiler can elide it entirely and then you have no problem.

Community
  • 1
  • 1
Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055