Any evaluation of a function called during the evaluation of a constant expression must not have any side effects. In C++11, the rules are actually much stricter, allowing only a single return
statement as function body but that's not relevant to this question.
The compiler is not entitled to remove any code from a constexpr
function in order to make it comply. It is your responsibility to not write such code in the first place.
However, it is okay to have code with side effects inside a constexpr
function if the control flow during static evaluation never passes through it.
This is valid C++11.
void g() { std::cout << "hello, world" << std::endl; }
constexpr bool f(const bool p = false) { return p ? (g(), false) : true; }
And you may call f
like this.
constexpr auto x = f(); // ok
Because p
is false
at compile-time, the compiler need not evaluate the call to g
. At run-time, you may call f
with either argument just as if it were not a constexpr
function.
f(false); // ok
f(true); // ok, produces output at run-time
What you cannot do is evaluate it in a constant expression with the parameter set to true
.
constexpr auto x = f(true); // compile-time error
Of course, this example is contrived beyond any restrictions and you should simply write
constexpr bool f() noexcept { return true; }
or use a variable
constexpr auto toggle = true;
if this is all you need.