7
votes
struct A
{
    A(int x)
        : n(x)
    {}

    A(A&&)
    {}

    A& operator =(A&&)
    {
        return *this;
    }

    int n;
};

int main()
{
    A a(1), b(2);

    a = b;

    if (2 == a.n)
    {
        // It SHOULD go here!
    }
}

As per the C++ standard 12.8.7:

If the class definition declares a move constructor or move assignment operator, the implicitly declared copy constructor is defined as deleted;

and 12.8.18

If the class definition declares a move constructor or move assignment operator, the implicitly declared copy assignment operator is defined as deleted;

The statement a = b; should trigger a compiler error. However, my compiler (VC++ 2013 RC) accepts it and calls the implicitly-defined copy assignment instead.

Is this a compiler's bug?

Update:

I have submitted this issue as a bug to microsoft.

1
"Is this a compiler's bug?" it wouldn't surprise me. MSVC handling of move ctors and move assignment op has always been lacking.Angew is no longer proud of SO
a = b wouldn't call the copy constructor, would it?Luchian Grigore
Isn't a = b a copy-assignment here? Your quote says the copy-constructor is deleted, not the copy-assignment operator.Useless
@Useless, because the copy-assignment should have been deleted, so it will trigger an error.xmllmx
@juanchopanza, my fault. I have added another quote.xmllmx

1 Answers

2
votes

This seems like a compiler bug indeed.

Since you have defined a user-provided move assignment operator, the copy assignment operator should be implicitly defined as deleted (as specified in 12.8.18). This is the behaviour exhibited by other compilers (gcc, for example).