Consider the following code:
struct S
{
constexpr S(){};
constexpr S(const S &r) { *this = r; };
constexpr S &operator=(const S &) { return *this; };
};
int main()
{
S s1{};
constexpr S s2 = s1; // OK
}
The above program is well-formed but I'm expecting it to be ill-formed, because [expr.const]/(5.16) says:
An expression
Eis a core constant expression unless the evaluation ofE, following the rules of the abstract machine ([intro.execution]), would evaluate one of the following:
- [..]
- (5.16) a modification of an object ([expr.ass], [expr.post.incr], [expr.pre.incr]) unless it is applied to a non-volatile lvalue of literal type that refers to a non-volatile object whose lifetime began within the evaluation of
E;- [..]
Given the expression E is s1. The expression E evaluates a modification of the object *this. The modification is applied to the non-volatile lvalue *this which is of literal type, and this lvalue refers to a non-volatile object which is s1 but the lifetime of s1 does not begin within the evaluation of E: That's the lifetime of the object s1 began before the evaluation of the expression E.
So I'm expecting the program is ill-formed because the "unless" part does not satisfy which means, to me, that the expression E is not a core constant expression. So what I'm missing here? Am I misreading (5.16)?