Search

Implicit copy constructor calls base with derived type under specific conditions. by Noah Roberts

Closed
as Won't Fix Help for as Won't Fix

1
0
Sign in
to vote
Type: Bug
ID: 587787
Opened: 8/20/2010 10:01:25 AM
Access Restriction: Public
0
Workaround(s)
0
User(s) can reproduce this bug
The implicit copy constructor passes the derived type rather than the base type to base copy constructors when using multiple inheritance and one or more base classes has a user defined copy constructor.
Details (expand)

Visual Studio/Silverlight/Tooling version

Visual Studio 2010

What category (if any) best represents this feedback?

 

Steps to reproduce


struct derived;

struct base
{
base() {}

private:
// Can be any constructor that will match derived
base(derived const&); // called by derived copy constructor result: C2248
};

struct base2
{
base2() {}
base2 (base2 const&) {} // <- causes problem.
};

struct derived : base, base2
{
derived() {}
// Fix:
//derived(derived const& d)
// : base(static_cast<base const&>(d))
// , base2(static_cast<base2 const&>(d)) {}
};

int main()
{
derived d1; derived d2(d1);
}

Product Language

English

Operating System

Windows 7

Operating System Language

English

Actual results

C2248

Expected results

Successful compile where derived's copy constructor calls the implicit copy constructor in base rather than an alternative constructor that can match the derived type.
File Attachments
0 attachments
Sign in to post a comment.
Posted by Victor Scherba on 1/11/2012 at 7:52 AM
Hi, it sems to be solved http://connect.microsoft.com/VisualStudio/feedback/details/651972/visual-c-copy-constructor-bug-for-base-class-with-template-constructor
Posted by Noah Roberts on 8/31/2010 at 2:23 PM
Your explanation doesn't seem to jive with the steps required to reproduce the problem. Simply having the "base(derived const&)" constructor in the base type is not enough. You have to use multiple inheritance and one of the OTHER base classes needs to have a user-defined copy constructor. In the code I put in this report, if you do not derive from base2 you will not get an error. The program both compiles and functions correctly.

Your explanation DOES jive with behavior in older versions of the compiler where removing the inheritance of base2 doesn't cause the issue to go away.
Posted by Microsoft on 8/31/2010 at 2:02 PM
Thank you for reporting this issue. It is a well known bug that's unfortunately hard to fix without doing a lot of work in the compiler. Here's the reason:

In 12.8/8, bullet 1, the Standard says that for an implicitly defined (i.e., compiler generated) copy constructor, the *copy* constructor for the base shall be called to initialize it. This has always been implemented in the compiler by generating a token stream for the implicitly defined copy constructor as:

<class-name>::<class-name>(const <class-name> & __arg) : <base-name>(__arg) {}

The problem is that in this form, different rules apply because of the base-initializer list. The Standard in this case states that "<base-name>(__arg)" shall be treated as a direct-initialization and this is the behaviour that you are seeing where any suitable constructor from the base-class can be chosen, and not just the copy-constructors. The workaround that you have is a correct one and will force the compiler to do the right thing but unfortunately can't be used in all cases (otherwise this bug would be simple to fix).

Tanveer Gani
Visual C++
Posted by Microsoft on 8/22/2010 at 7:23 PM
Thank you for reporting the issue.
We are routing this issue to the appropriate group within the Visual Studio Product Team for triage and resolution.These specialized experts will follow-up with your issue.
Posted by Microsoft on 8/20/2010 at 5:02 PM
Thank you for your feedback, we are currently reviewing the issue you have submitted. If this issue is urgent, please contact support directly(http://support.microsoft.com)
Sign in to post a workaround.