Reputation: 667
int d = 1;
constexpr void add()
{
d++;
}
int main()
{
}
GCC 7.1 will report errors below. The error message is very clear. The problem is that I don't see any explicit explanations in constexpr to describe it's illegal.
Can someone explain which rules defined in spec this case violate?
main.cpp: In function 'constexpr void add()': main.cpp:8:1: error: the value of 'd' is not usable in a constant expression } ^ main.cpp:4:5: note: 'int d' is not const int d = 1; ^
Upvotes: 1
Views: 410
Reputation: 6037
From cppreference:
A core constant expression is any expression that does not have any one of the following in any subexpression (ignoring unevaluated expressions such as the operand of sizeof or the right operand of builtin && when the left operand evaluates to false).
...
16) modification of an object, unless the object has non-volatile literal type and its lifetime began within the evaluation of the expression.
In your example, d
's lifetime began before add
was evaluated - so any modification of d
inside add
is illegal. The example on the reference is specifically for incrementing, but this holds for all modifications.
Edit: Not quoting from the standard because as far as I'm aware, you've got to buy it...
Upvotes: 2
Reputation: 878
The comments are good from a refer-you-to-the-standard perspective, but here hopefully a more intuitive explanation.
A constexpr
function must be reducible to a constant expression at compile time. Since you are interacting with a regular, non-const
int
in the function, the compiler cannot determine what d++
is under all circumstances. Consider the following case:
int d;
constexpr void add() {
d++;
}
void foo() {
int n;
std::cin >> n;
d = n;
add();
}
In this case, the value of d
inside foo()
is indeterminate at compile time, and therefore, the constant expression that you are hoping add()
to leave you with cannot be determined. I hope that helps.
Upvotes: 0