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".

Reply via email to