The rules for constexpr functions constexpr designed in such a way that it is impossible to write a constexpr function that has any side effects.
If constexpr is required to have no side effects, the user cannot determine where / when it was actually evaluated. This is important because constexpr functions constexpr allowed both at compile time and at run time at the discretion of the compiler.
If side effects were resolved, then there should be some rules about the order in which they will be observed. That would be incredibly hard to define - even harder than the static initialization order issue.
A relatively simple set of rules guaranteeing free access to these functions should require that they be just one expression (with some additional restrictions on this). This sounds limited at first, and as you noted, excludes the if statement. Although there would be no side effects in this particular case, it would introduce additional complexity into the rules and provided that you can write the same things with the ternary operator or recursively this is not a big deal.
n2235 is an article that suggested the addition of constexpr in C ++. It discusses the rational for design - the corresponding quote seems to be from the discussion of destructors, but in general it matters:
The reason is that the constant expression is intended to be evaluated by the compiler during translation, like any other literal of a built-in type; in particular, no observable side effect is allowed.
Interestingly, the document also mentions that in the previous sentence it was assumed that the compiler automatically figured out what functions were constexpr without a new keyword, but this turned out to be inoperative, which seems to confirm my assumption that the rules were designed to be simple.
(I suspect there will be other citations in the links cited in the article, but this is about the key point of my side effect argument)
Flexo Nov 29 '11 at 3:26 a.m. 2011-11-29 15:26
source share