Почему функция constexpr оценивается не во время компиляции, а во время выполнения в операторе возврата основной функции?
попробовал
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;
}
и результат
main:
push rbp
mov rbp, rsp
mov DWORD PTR [rbp-4], 6
mov eax, 6
pop rbp
ret
с gcc 8.2. Но когда я вызываю функцию в операторе возврата
template<int x>
constexpr int fac() {
return fac<x - 1>() * x;
}
template<>
constexpr int fac<1>() {
return 1;
}
int main() {
return fac<3>();
}
Я получаю
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
Почему первый код оценивается во время компиляции, а второй - во время выполнения?
Также я попробовал оба фрагмента clang 7.0.0, и они оцениваются во время выполнения. Почему этот недействительный constexpr для clang?
Вся оценка была выполнена в проводнике компилятора Godbolt.