'Why does clang complain about a deleted move ctor when I don't move anything?

Premise :

#include <iostream>
using namespace std;

class ABC {
 public:

   ABC() {
     cout << "Default constructor ..\n";
   }

   ABC(const ABC& a) {
     cout << "In copy constrcutor ..\n";
   }
   ABC(ABC&& aa) = delete;
};

int main(int argc, char* argv[]) {
  ABC b{ABC{}};
  return 0;
}

Compile this with GCC vs Clang

Clang - Apple LLVM version 8.1.0 (clang-802.0.42)

Gcc - 5.4.0 ubuntu

Observation Clang complains about deleted Move constructor.

Gcc does not complain at all. And will output correctly.

Question Why?

For gcc, I know that if you are simply initializing both lvalue and rvalue, it optimizes and does not actually call the copy constructor and copy the temporary to the lvalue.

Why does Clang differ? I thought (not sure, hence the question) this was in C++ standard, which one deviated (or not)? Or am I doing something wrong.

Compilation command : g++ --std=c++11 -O3 file.cpp

For additional fun, remove curly braces and put parenthesis instead ;)

ABC b{ABC{}}; to, ABC b(ABC());, Unrelated to this question.

EDIT : Someone marked the question as a dup, which it is not. I clearly state that I think C++11 standard includes copy elision. However, CLANG does not seem to have the same behavior on something as critical as constructors.

HERE Is the LINK : http://en.cppreference.com/w/cpp/language/copy_elision

clearly, it says C++11. I trust cppref.



Solution 1:[1]

EDIT : Someone marked the question as a dup, which it is not. I clearly state that I think C++11 standard includes copy elision. However, CLANG does not seem to have the same behavior on something as critical as constructors.

HERE Is the LINK : http://en.cppreference.com/w/cpp/language/copy_elision

clearly, it says C++11. I trust cppref.

It was me who marked it as a dupe. From the page you linked:

Under the following circumstances, the compilers are permitted, but not required to omit the copy- and move- (since C++11)construction

When a nameless temporary, not bound to any references, would be copied or moved (since C++11) into an object of the same type (ignoring top-level cv-qualification), the copy/move (since C++11) is omitted. (until C++17)

This optimization is mandatory; see above. (since C++17)

As you can see move constructor will be required because copy elision is not a requirement but recommendation pre C++17. C++17 compilers should not complain about deleted move constructor under the same circumstance.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Community