Answer
A constexpr function must be able to produce a compile-time constant when given constant arguments: historically its body was limited (single return in C++11), but C++14+ allows loops, local variables, and multiple statements. It can't have side effects that aren't allowed in constant evaluation (no I/O, no non-constexpr calls, no undefined behavior). If used in a runtime context, it runs normally.
constexpr int fib(int n) {
int a = 0, b = 1;
for (int i = 0; i < n; ++i) { int t=a; a=b; b=t+b; }
return a;
}Real-world example A constexpr fib is used to size a compile-time array, forcing the computation into the build.