Why is a constexpr function no evaluated at compile time but in runtime in the return statement of main function?
It tried
template<int x>
constexpr int fac() {
return fac<x - 1>() * x;
}
template<>
constexpr int fac<1>() {
return 1;
}
int main() {
const int x = fac<3>();
return x;
}
and the result is
main:
push rbp
mov rbp, rsp
mov DWORD PTR [rbp-4], 6
mov eax, 6
pop rbp
ret
with gcc 8.2. But when I call the function in the return statement
template<int x>
constexpr int fac() {
return fac<x - 1>() * x;
}
template<>
constexpr int fac<1>() {
return 1;
}
int main() {
return fac<3>();
}
I get
int fac<1>():
push rbp
mov rbp, rsp
mov eax, 1
pop rbp
ret
main:
push rbp
mov rbp, rsp
call int fac<3>()
nop
pop rbp
ret
int fac<2>():
push rbp
mov rbp, rsp
call int fac<1>()
add eax, eax
pop rbp
ret
int fac<3>():
push rbp
mov rbp, rsp
call int fac<2>()
mov edx, eax
mov eax, edx
add eax, eax
add eax, edx
pop rbp
ret
Why is the first code evaluated at compile time and the second at runtime?
Also I tried both snippets with clang 7.0.0 and they are evaluated at runtime. Why is this not valid constexpr for clang?
All evaluation was done in godbolt compiler explorer.
-O3for optimal behaviour, the question is meaningless without it. As posted the question is really about "why does the compiler without optimization do this thing" to which the answer is usually "to make debugging easier" - M.Mconstexprexists to let you write natural code for producing constant expressions in contexts that need them. It's not a "optimize this to heck always" hint to the compiler. It's best not to confuse it for one. - StoryTeller - Unslander Monicaconstexpris to tell the compiler "this should be evaluated at compile time", while I now understand that it is rather "this must be evaluatable at compile time". Suddenly the confusion about whether it does get evaluated at compile time or not feels much less severe. - 463035818_is_not_a_numberxas a template parameter. An "ordinary" parameter will suffice here. So, you can useconstexprfunctions as a more readable replacement for some old style meta-programming-template-code that previously had to be used to generate compile time integers. - sebrockm