Reputation: 41
These demo functions should not be infinite loops in gcc because the conditional operator should only evaluate the active part.
They compile correctly in visual studio 2015 but give infinite recursion error compile error in g++ 6.3. What am I missing?
template <int n>
constexpr int infinite_loop_error(){
return (n) ? infinite_loop_error<n - 1>() : 0;
}
template <int n>
constexpr int infinite_loop_error_2(){
if (n) return infinite_loop_error_2<n - 1>();
else return 0;
}
void main() {
infinite_loop_error<3>();
infinite_loop_error_2<3>();
}
Upvotes: 3
Views: 235
Reputation: 138051
This is a bug in MSVC, your program shouldn't compile. You are mixing up runtime recursion and compile-time recursion.
While the program should only evaluate one hand of the ternary expression at runtime, the compiler still needs to generate code for both hands of the ternary expression (and for both branches of the if
condition). Your program fails during code generation because the compiler can't find a point where it can stop. MSVC "succeeds" because it applies optimizations too early, infringing on the as-if rule.
You need to use a template specialization as a stopping condition:
template <int n>
constexpr int infinite_loop_error(){
return (n) ? infinite_loop_error<n - 1>() : 0;
}
template <>
constexpr int infinite_loop_error<0>(){
return 0;
}
template <int n>
constexpr int infinite_loop_error_2(){
if (n) return infinite_loop_error_2<n - 1>();
else return 0;
}
template <>
constexpr int infinite_loop_error_2<0>(){
return 0;
}
int main() {
infinite_loop_error<3>();
infinite_loop_error_2<3>();
}
Instead of instantiating infinite_loop_error<0>
from the definition that will make it recurse further, the compiler uses the definition that you provide for it and compile-time recursion correctly stops.
Upvotes: 7