https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114110
Bug ID: 114110 Summary: unhelpful message about non-movable types Product: gcc Version: 12.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: f.heckenb...@fh-soft.de Target Milestone: --- Here's another gcc output that's less than helpful: % cat test.cpp #include <utility> #include <memory> struct S { std::unique_ptr <int> a, b, c, d, e, f, g, h, i, j; ~S () = default; }; int main () { S a, b = std::move (a); } % g++ test.cpp test.cpp: In function 'int main()': test.cpp:12:24: error: use of deleted function 'S::S(const S&)' 12 | S a, b = std::move (a); | ^ test.cpp:4:8: note: 'S::S(const S&)' is implicitly deleted because the default definition would be ill-formed: 4 | struct S | ^ test.cpp:4:8: error: use of deleted function 'std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = int; _Dp = std::default_delete<int>]' In file included from /usr/include/c++/12/memory:76, from test.cpp:2: /usr/include/c++/12/bits/unique_ptr.h:514:7: note: declared here 514 | unique_ptr(const unique_ptr&) = delete; | ^~~~~~~~~~ test.cpp:4:8: error: use of deleted function 'std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = int; _Dp = std::default_delete<int>]' 4 | struct S | ^ /usr/include/c++/12/bits/unique_ptr.h:514:7: note: declared here 514 | unique_ptr(const unique_ptr&) = delete; | ^~~~~~~~~~ test.cpp:4:8: error: use of deleted function 'std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = int; _Dp = std::default_delete<int>]' 4 | struct S | ^ /usr/include/c++/12/bits/unique_ptr.h:514:7: note: declared here 514 | unique_ptr(const unique_ptr&) = delete; | ^~~~~~~~~~ test.cpp:4:8: error: use of deleted function 'std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = int; _Dp = std::default_delete<int>]' 4 | struct S | ^ /usr/include/c++/12/bits/unique_ptr.h:514:7: note: declared here 514 | unique_ptr(const unique_ptr&) = delete; | ^~~~~~~~~~ test.cpp:4:8: error: use of deleted function 'std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = int; _Dp = std::default_delete<int>]' 4 | struct S | ^ /usr/include/c++/12/bits/unique_ptr.h:514:7: note: declared here 514 | unique_ptr(const unique_ptr&) = delete; | ^~~~~~~~~~ test.cpp:4:8: error: use of deleted function 'std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = int; _Dp = std::default_delete<int>]' 4 | struct S | ^ /usr/include/c++/12/bits/unique_ptr.h:514:7: note: declared here 514 | unique_ptr(const unique_ptr&) = delete; | ^~~~~~~~~~ test.cpp:4:8: error: use of deleted function 'std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = int; _Dp = std::default_delete<int>]' 4 | struct S | ^ /usr/include/c++/12/bits/unique_ptr.h:514:7: note: declared here 514 | unique_ptr(const unique_ptr&) = delete; | ^~~~~~~~~~ test.cpp:4:8: error: use of deleted function 'std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = int; _Dp = std::default_delete<int>]' 4 | struct S | ^ /usr/include/c++/12/bits/unique_ptr.h:514:7: note: declared here 514 | unique_ptr(const unique_ptr&) = delete; | ^~~~~~~~~~ test.cpp:4:8: error: use of deleted function 'std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = int; _Dp = std::default_delete<int>]' 4 | struct S | ^ /usr/include/c++/12/bits/unique_ptr.h:514:7: note: declared here 514 | unique_ptr(const unique_ptr&) = delete; | ^~~~~~~~~~ test.cpp:4:8: error: use of deleted function 'std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = int; _Dp = std::default_delete<int>]' 4 | struct S | ^ /usr/include/c++/12/bits/unique_ptr.h:514:7: note: declared here 514 | unique_ptr(const unique_ptr&) = delete; | ^~~~~~~~~~ gcc explains in much detail (and not very readable, cf. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113854#c4, esp. the bottom part), repeating the same message for each member, why the type is not copyable. Well, I know it's not copyable, that's why I'm trying to move it. Sure, a copy-constructor can be used when there is no useable move-constructor, but if both copy- and move-constructor are not useable, it's quite misleading to only explain why the copy-constructor is not useable when moving was requested in the first place. The actual problem here is that the move-constructor was deleted because a destructor was declared, but gcc does not mention this at all (instead of, or at least in addition to, why the copy-constructor was deleted). Of course, as usual, in a vastly simplified example like this, it's easy to see the problem, but in more complex real code with many members and class hierarchies, it's not so obvious and the output doesn't tell me anything but "something's wrong here".