Re: Implicit move constructor rules in c++0x still badly broken?
On 14.02.2011 13:20, Patrik Kahari wrote:
Dave Abrahams came up with the following example that still breaks
with the new rules. I think it is quite serious, as the code looks
perfectly innocent and a non-expert would not have a clue why it
broke. What do you guys think?
<code> -- [snipped!] --
As found in the comment of
http://cpp-next.com/archive/2011/02/w00t-w00t-nix-nix/
Unfortunately, with that code by itself I felt it was rather hard to
understand the problem. Since I just tried anyway, let me try to
summarize the problem how I understood it:
In 2010/10 [1] Dave posted how implicit move is broken in several ways.
One example looked like this:
struct X {
// invariant: v.size() == 5
X() : v(5) {}
~X()
{
std::cout << v[0] << std::endl;
}
private:
std::vector<int> v;
};
The implicitly generated move however would break the invariant, because
in the moved-from state the vector would have zero elements.
Later, the committee tightened the rules for implicitly generated
move-operations, and I'll just quote Dave [2] here:
[q]
If the class definition of a class X
does not explicitly declare a move
constructor, one will be implicitly
declared as defaulted if and only if
* X does not have a user-declared copy constructor
* X does not have a user-declared copy assignment operator,
* X does not have a user-declared move assignment operator,
* X does not have a user-declared destructor, and
* the move constructor would not be implicitly defined as deleted.
[/q]
Seeing as in the struct X above, the dtor is fully optional, moving-from
will *still* leave this class in an invalid state, as all rules are
fulfilled.
I hope I got the problem correctly.
NOW, TO MY QUESTION:
It seems to me that *not* the rules for implicit move-op generation are
broken, but instead the rules for creating the default move ctor.
If I understand correctly the default move ctor will zero-initialize all
members of the moved-from object (Correct??). This *seems wrong*, as
with the struct X above, there is -- at first -- no way to create an
instance of X that has zero-initialized members.
Adding a move-ctor to this class however, will introduce such a state to
the class, even though the default ctor does not allow for this state.
(Correct??)
Does that make sense?
cheers,
Martin
[1] Implicit Move Must Go:
http://cpp-next.com/archive/2010/10/implicit-move-must-go/
[2] Comment on W00t W00t Nix Nix!:
http://cpp-next.com/archive/2011/02/w00t-w00t-nix-nix/comment-page-1/#comment-1321
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]