Consider the following example:
class X {
public:
X() = default;
X(const X&) = default;
X(X&&) = delete;
};
X foo() {
X result;
result
is not an lvalue after returning from foo()
, but a prvalue, so it is allowed to call the move constructor.
From CppReference:
The following expressions are prvalue expressions:
- a function call or an overloaded operator expression, whose return type is non-reference, such as
str.substr(1, 2)
,str1 + str2
, orit++
It is possible that Clang detected that the return value is unused and threw it away directly, while GCC didn't.