C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

virtual inheritance and operator=
Goto page 1, 2  Next
 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated)
View previous topic :: View next topic  
Author Message
Michael Mellor
Guest





PostPosted: Mon Jan 26, 2004 8:25 pm    Post subject: virtual inheritance and operator= Reply with quote



Take the following example of virtual inheritance:
#include <iostream>

struct Base {
Base &operator= ( const Base &a ) {
std::cout << "Basen";
return *this;
}
};

struct DervA : virtual public Base {
DervA &operator= ( const DervA &a ) {
std::cout << "DervAn";
return *this;
}
};

struct DervB : virtual public Base {
DervB &operator= ( const DervB &a ) {
std::cout << "DervBn";
return *this;
}
};

struct Derv2 : public DervA , public DervB {
};

int main ( ) {
Derv2 a, b;
a = b;
}

Visual C++ 7.0 gives:
Base
DervA
DervB

g++ 3.3.1 gives:
DervA
DervB

What is the correct behaviour?


Now if I change the code to:
.....
struct DervA : virtual public Base {
};

struct DervB : virtual public Base {
};
....
g++ gives:
Base
Base

Visual C++ 7.0 gives:
Base

If this is a bug in g++ does anyone know a link to the bug report?

Michael Mellor

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Jonathan Turkanis
Guest





PostPosted: Tue Jan 27, 2004 10:49 am    Post subject: Re: virtual inheritance and operator= Reply with quote



"Michael Mellor" <news-at- (AT) michaelmellor-dot- (DOT) com> wrote

Quote:
Take the following example of virtual inheritance:
#include
struct Base {
Base &operator= ( const Base &a ) {
std::cout << "Basen";
return *this;
}
};

struct DervA : virtual public Base {
DervA &operator= ( const DervA &a ) {
std::cout << "DervAn";
return *this;
}
};

struct DervB : virtual public Base {
DervB &operator= ( const DervB &a ) {
std::cout << "DervBn";
return *this;
}
};

struct Derv2 : public DervA , public DervB {
};

int main ( ) {
Derv2 a, b;
a = b;
}

Visual C++ 7.0 gives:
Base
DervA
DervB

g++ 3.3.1 gives:
DervA
DervB

What is the correct behaviour?

There's no single correct behavior. From 12.8/13:

The implicitly-defined copy assignment operator for class X
performs memberwise assignment of its subobjects. ...
It is unspecified whether subobjects representing virtual base
classes are assigned more than once by the implicitly-defined
copy assignment operator. [Example:
struct V { };
struct A : virtual V { };
struct B : virtual V { };
struct C : B, A { };
it is unspecified whether the virtual base class subobject V is
assigned twice by the implicitly-defined
copy assignment operator for C. -end example]

This makes it clear that

Base
DervA
Base
DervB

would be an acceptable output, but I don't know of a compiler that
does this. I read the above passage to rule out the g++ 3.3.1
behavior, but I'm not sure. A number of other compilers also behave
this way.

Jonathan



[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
kanze@gabi-soft.fr
Guest





PostPosted: Tue Jan 27, 2004 6:36 pm    Post subject: Re: virtual inheritance and operator= Reply with quote



Michael Mellor <news-at- (AT) michaelmellor-dot- (DOT) com> wrote

Quote:
Take the following example of virtual inheritance:
#include
struct Base {
Base &operator= ( const Base &a ) {
std::cout << "Basen";
return *this;
}
};

struct DervA : virtual public Base {
DervA &operator= ( const DervA &a ) {
std::cout << "DervAn";
return *this;
}
};

struct DervB : virtual public Base {
DervB &operator= ( const DervB &a ) {
std::cout << "DervBn";
return *this;
}
};

struct Derv2 : public DervA , public DervB {
};

int main ( ) {
Derv2 a, b;
a = b;
}

Visual C++ 7.0 gives:
Base
DervA
DervB

g++ 3.3.1 gives:
DervA
DervB

What is the correct behaviour?

G++. The implicitly defined copy assignment operator should perform
memberwise assignment of its direct base classes, in the order of their
declaration. Derv2 has two direct base classes, DervA and DervB. Both
have user defined assignment operators, so these are used for the
memberwise assignment.

Note that if you declared Derv2:

struct Derv2 : DervA, DervB, virtual Base {} ;

then the situation would be different.

Note too that with your declarations, it is the responsibility of the
user defined assignment operators in DervA and DervB to invoke the
assignment operator of Base. If you only want it invoked once, you have
a problem. Solutions exist, but they all involve the participation of
Derv2 in one way or another. In sum, Derv2 must know about the virtual
bases of DervA and DervB.

Note that, generally, assignment and derivation don't work well
together. This is especially true if the derivation is virtual.

Quote:
Now if I change the code to:
....
struct DervA : virtual public Base {
};

struct DervB : virtual public Base {
};
...
g++ gives:
Base
Base

Visual C++ 7.0 gives:
Base

If this is a bug in g++ does anyone know a link to the bug report?

It's a bug in VC++. Although VC++ is arguably providing the more useful
behavior, the standard requires the behavior of G++. Basically, the
compiler generated copy assignment of Derv2 calls the copy assignment
operator of DervA and DervB. The compiler generated copy assignment for
DervA and for DervB each invoke the assignment operator of their direct
(declared) bases, i.e. Base.

As for why the standard requires this: you do want the compiler
generated operator to conform to something you could write yourself.
And there is no (trivial) way of writing user defined assignment
operators which give the behavior of VC++ here.

--
James Kanze GABI Software mailto:kanze (AT) gabi-soft (DOT) fr
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Thomas Mang
Guest





PostPosted: Tue Jan 27, 2004 6:40 pm    Post subject: Re: virtual inheritance and operator= Reply with quote



Jonathan Turkanis schrieb:

Quote:
"Michael Mellor" <news-at- (AT) michaelmellor-dot- (DOT) com> wrote in message
news:bv3j0d$toe$1 (AT) news8 (DOT) svr.pol.co.uk...
Take the following example of virtual inheritance:
#include
struct Base {
Base &operator= ( const Base &a ) {
std::cout << "Basen";
return *this;
}
};

struct DervA : virtual public Base {
DervA &operator= ( const DervA &a ) {
std::cout << "DervAn";
return *this;
}
};

struct DervB : virtual public Base {
DervB &operator= ( const DervB &a ) {
std::cout << "DervBn";
return *this;
}
};

struct Derv2 : public DervA , public DervB {
};

int main ( ) {
Derv2 a, b;
a = b;
}

Visual C++ 7.0 gives:
Base
DervA
DervB

g++ 3.3.1 gives:
DervA
DervB

What is the correct behaviour?

There's no single correct behavior. From 12.8/13:

The implicitly-defined copy assignment operator for class X
performs memberwise assignment of its subobjects. ...
It is unspecified whether subobjects representing virtual base
classes are assigned more than once by the implicitly-defined
copy assignment operator. [Example:
struct V { };
struct A : virtual V { };
struct B : virtual V { };
struct C : B, A { };
it is unspecified whether the virtual base class subobject V is
assigned twice by the implicitly-defined
copy assignment operator for C. -end example]

This makes it clear that

Base
DervA
Base
DervB

would be an acceptable output, but I don't know of a compiler that
does this. I read the above passage to rule out the g++ 3.3.1
behavior, but I'm not sure. A number of other compilers also behave
this way.

I find the whole text about it in the Standard quite confusing.

There is some important wording in 12.8/13 you did not quote:

"The implicitly-defined copy assignment operator for class X performs
memberwise assignment of its subobjects. The direct base classes of X
are assigned first, in the order of their declaration in the
base-specifier list, and then the ...."

Note, it says only about direct base classes, nothing about virtual base
classes.

Then it continues:

"It is unspecified whether subobjects representing virtual base classes
are assigned more than once by the implicitly-defined copy assignment
opertaor. [Example:

struct V{};
sturct A : virtual V{};
struct B: virtual V{};
struct C : B, A{};

it is unspecified whether the virtual base class subobject V is assigned
twice by the implicitly-defined copy assignment operator for C. -end
example]".


Note that now the Standard talks about C being responsible for
assignment to V, which is a contradiction to the paragraph I quoted
above, where only about direct base classes is talked.

Is this a defect?


regards,

Thomas

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Francis Glassborow
Guest





PostPosted: Tue Jan 27, 2004 6:41 pm    Post subject: Re: virtual inheritance and operator= Reply with quote

In message <bv415g$o6hu8$1 (AT) ID-216073 (DOT) news.uni-berlin.de>, Jonathan
Turkanis <technews (AT) kangaroologic (DOT) com> writes
Quote:
There's no single correct behavior. From 12.8/13:

When drafting that part of the Standard we (and I was one of those
actually involved) tried to find a way that we could specify that copy
assignment would work effectively as does copy construction. In the end
we came to the conclusion that actually requiring that behaviour would
result in bad implementations in some cases.

Quote:

The implicitly-defined copy assignment operator for class X
performs memberwise assignment of its subobjects. ...
It is unspecified whether subobjects representing virtual base
classes are assigned more than once by the implicitly-defined
copy assignment operator. [Example:
struct V { };
struct A : virtual V { };
struct B : virtual V { };
struct C : B, A { };
it is unspecified whether the virtual base class subobject V is
assigned twice by the implicitly-defined
copy assignment operator for C. -end example]

This makes it clear that

Base
DervA
Base
DervB

would be an acceptable output, but I don't know of a compiler that
does this. I read the above passage to rule out the g++ 3.3.1
behavior, but I'm not sure. A number of other compilers also behave
this way.

Yes, we phrased the requirement is in such a way as to encourage
compilers to avoid unnecessary duplication. However the difficult cases
only arise with much larger sub-object lattices (which was why we
continually found problems with requiring that virtual sub-objects be
assigned to only once.

What makes it particularly difficult is that the rules for user written
copy assignments are unlike those for copy ctors. Once you take control
of assignment you are responsible for all of it from then on out (or you
get surprises:( )


--
Francis Glassborow ACCU
Author of 'You Can Do It!' see http://www.spellen.org/youcandoit


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
JarlOstensen
Guest





PostPosted: Tue Jan 27, 2004 6:42 pm    Post subject: Re: virtual inheritance and operator= Reply with quote

Michael Mellor <news-at- (AT) michaelmellor-dot- (DOT) com> wrote

Quote:
Take the following example of virtual inheritance:
#include
struct Base {
Base &operator= ( const Base &a ) {
std::cout << "Basen";
return *this;
}
};

struct DervA : virtual public Base {
DervA &operator= ( const DervA &a ) {
std::cout << "DervAn";
return *this;
}
};

struct DervB : virtual public Base {
DervB &operator= ( const DervB &a ) {
std::cout << "DervBn";
return *this;
}
};

struct Derv2 : public DervA , public DervB {
};

int main ( ) {
Derv2 a, b;
a = b;
}

Visual C++ 7.0 gives:
Base
DervA
DervB

g++ 3.3.1 gives:
DervA
DervB

What is the correct behaviour?


I could only find references to implicitly-defined assignment
operators and virtual inheritance in The Standard, (see below), but in
this case my money would be on VC 7.0, (and 7.1 which has the same
behaviour).


Quote:

Now if I change the code to:
....
struct DervA : virtual public Base {
};

struct DervB : virtual public Base {
};
...
g++ gives:
Base
Base

Visual C++ 7.0 gives:
Base

If this is a bug in g++ does anyone know a link to the bug report?

In this last case gcc doesn't do anything wrong since, (as The

Standard says in 12.Cool, it is unspecified if the base class assignment
operator is invoked twice in this case. (in the case of
implicitly-defined assignment operators!)

Quote:
Michael Mellor

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

According to the

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Michael Mellor
Guest





PostPosted: Tue Jan 27, 2004 6:46 pm    Post subject: Re: virtual inheritance and operator= Reply with quote

Jonathan Turkanis wrote:
Quote:
"Michael Mellor" <news-at- (AT) michaelmellor-dot- (DOT) com> wrote in message
news:bv3j0d$toe$1 (AT) news8 (DOT) svr.pol.co.uk...
Take the following example of virtual inheritance:
#include <iostream

struct Base {
Base &operator= ( const Base &a ) {
std::cout << "Basen";
return *this;
}
};

struct DervA : virtual public Base {
DervA &operator= ( const DervA &a ) {
std::cout << "DervAn";
return *this;
}
};

struct DervB : virtual public Base {
DervB &operator= ( const DervB &a ) {
std::cout << "DervBn";
return *this;
}
};

struct Derv2 : public DervA , public DervB {
};

int main ( ) {
Derv2 a, b;
a = b;
}

Visual C++ 7.0 gives:
Base
DervA
DervB

g++ 3.3.1 gives:
DervA
DervB

What is the correct behaviour?

There's no single correct behavior. From 12.8/13:

The implicitly-defined copy assignment operator for class X
performs memberwise assignment of its subobjects. ...
It is unspecified whether subobjects representing virtual base
classes are assigned more than once by the implicitly-defined
copy assignment operator. [Example:
struct V { };
struct A : virtual V { };
struct B : virtual V { };
struct C : B, A { };
it is unspecified whether the virtual base class subobject V is
assigned twice by the implicitly-defined
copy assignment operator for C. -end example]

[...]
From my understanding g++ has got it right as I am not calling the

operator= for the base class and this is a bug in Visual C++ 7.0.

However, if I put this through g++ 3.3.1:
#include
static int c = 100;

struct Base {
Base ( ) : n(c++) { std::cout << "base-" << n << "n"; }
Base &operator= ( const Base &other ) {
std::cout << "this-" << n << "n";
std::cout << "other-" << other.n << "n";
return *this;
}
int n;
};

struct DervA : virtual public Base { };

struct DervB : virtual public Base { };

struct Derv2 : public DervA , public DervB { };

int main ( ) {
Derv2 a, b;
a = b;
}

The result is:
base-100
base-101
this-4403668
other-101
this-100
other-101

which is obviously wrong so i get the impression operator= and virtual
inheritance is still not completely supported by modern compilers.

Michael Mellor

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Ben Hutchings
Guest





PostPosted: Wed Jan 28, 2004 9:47 am    Post subject: Re: virtual inheritance and operator= Reply with quote

Jonathan Turkanis wrote:
Quote:
"Michael Mellor" <news-at- (AT) michaelmellor-dot- (DOT) com> wrote in message
news:bv3j0d$toe$1 (AT) news8 (DOT) svr.pol.co.uk...
Take the following example of virtual inheritance:
snip

[abridged code]
struct Base {
Base &operator= ( const Base &a ) { return *this; }
};
struct DervA : virtual public Base {
DervA &operator= ( const DervA &a ) { return *this; }
};
struct DervB : virtual public Base {
DervB &operator= ( const DervB &a ) { return *this; }
};
struct Derv2 : public DervA , public DervB {
};

[order in which copy-assignment operators are called by Derv2's
copy-assignment operator]
Quote:
Visual C++ 7.0 gives:
Base
DervA
DervB

VC++ appears to be treating copy-assignment of a class with virtual
bases in a similar way to the construction of such a class, i.e.
calling virtual bases before non-virtual direct bases.

Adding a second virtual base class Base2 to the end of Derv2's base
list results in the obviously wrong:

Base
Base2
DervA
DervB

Quote:
g++ 3.3.1 gives:
DervA
DervB

What is the correct behaviour?

There's no single correct behavior. From 12.8/13:
snip

[operation of implicitly-defined copy-assignment operator in class
with virtual bases]
Quote:
This makes it clear that

Base
DervA
Base
DervB

would be an acceptable output, but I don't know of a compiler that
does this. I read the above passage to rule out the g++ 3.3.1
behavior, but I'm not sure. A number of other compilers also behave
this way.

Only Derv2 has an implicitly-defined copy-assignment operator. That
should only call copy-assignment operators for direct bases. The
copy-assignment operators for DervA and DervB don't call that for
Base, so I think VC++ is wrong and g++ is right.

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
John Potter
Guest





PostPosted: Wed Jan 28, 2004 1:19 pm    Post subject: Re: virtual inheritance and operator= Reply with quote

On 27 Jan 2004 05:49:41 -0500, "Jonathan Turkanis"
<technews (AT) kangaroologic (DOT) com> wrote:

Quote:
"Michael Mellor" <news-at- (AT) michaelmellor-dot- (DOT) com> wrote in message
news:bv3j0d$toe$1 (AT) news8 (DOT) svr.pol.co.uk...

What is the correct behaviour?

There's no single correct behavior.

Correct.

Quote:
From 12.8/13:

The implicitly-defined copy assignment operator for class X
performs memberwise assignment of its subobjects. ...
It is unspecified whether subobjects representing virtual base
classes are assigned more than once by the implicitly-defined
copy assignment operator. [Example:
struct V { };
struct A : virtual V { };
struct B : virtual V { };
struct C : B, A { };
it is unspecified whether the virtual base class subobject V is
assigned twice by the implicitly-defined
copy assignment operator for C. -end example]

This makes it clear that

Base
DervA
Base
DervB

would be an acceptable output,

Correct.

Quote:
but I don't know of a compiler that
does this.

Gcc will do that if you let it define the operator= for the two
derived classes. The compiler defined operator= for Derv2 calls
the two user defined operators for the two base classes. Those
user defined operators fail to call the Base operator=. The
compiler generated operator= calls the Base operator=. You will
see Base twice.

Quote:
I read the above passage to rule out the g++ 3.3.1
behavior, but I'm not sure.

It is conforming. If you want specific behavior, you must also
write the Derv2::operator= to get the compiler out of the
picture.

John

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Jonathan Turkanis
Guest





PostPosted: Wed Jan 28, 2004 1:24 pm    Post subject: Re: virtual inheritance and operator= Reply with quote


<kanze (AT) gabi-soft (DOT) fr> wrote

Quote:
Michael Mellor <news-at- (AT) michaelmellor-dot- (DOT) com> wrote in message


Quote:

... Derv2 has two direct base classes, DervA and DervB. Both
have user defined assignment operators,

Right, that's what I missed. I was treating them as if they were
implicitly defined.

Jonathan



[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Thomas Mang
Guest





PostPosted: Wed Jan 28, 2004 1:30 pm    Post subject: Re: virtual inheritance and operator= Reply with quote



[email]kanze (AT) gabi-soft (DOT) fr[/email] schrieb:

Quote:
Michael Mellor <news-at- (AT) michaelmellor-dot- (DOT) com> wrote in message
news:<bv3j0d$toe$1 (AT) news8 (DOT) svr.pol.co.uk>...
Take the following example of virtual inheritance:
#include
struct Base {
Base &operator= ( const Base &a ) {
std::cout << "Basen";
return *this;
}
};

struct DervA : virtual public Base {
DervA &operator= ( const DervA &a ) {
std::cout << "DervAn";
return *this;
}
};

struct DervB : virtual public Base {
DervB &operator= ( const DervB &a ) {
std::cout << "DervBn";
return *this;
}
};

struct Derv2 : public DervA , public DervB {
};

int main ( ) {
Derv2 a, b;
a = b;
}

Visual C++ 7.0 gives:
Base
DervA
DervB

g++ 3.3.1 gives:
DervA
DervB

What is the correct behaviour?

G++. The implicitly defined copy assignment operator should perform
memberwise assignment of its direct base classes, in the order of their
declaration. Derv2 has two direct base classes, DervA and DervB. Both
have user defined assignment operators, so these are used for the
memberwise assignment.

That's the behavior descibed in the first part of 12.8/13, but the example
later in the same paragraph seems to contradict it and push the
responsibility to the most derived class.


regards,

Thomas

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Jonathan Turkanis
Guest





PostPosted: Wed Jan 28, 2004 1:39 pm    Post subject: Re: virtual inheritance and operator= Reply with quote


"Thomas Mang" <a9804814 (AT) unet (DOT) univie.ac.at> wrote


Quote:
There is some important wording in 12.8/13 you did not quote:

"The implicitly-defined copy assignment operator for class X
performs
memberwise assignment of its subobjects. The direct base classes of
X
are assigned first, in the order of their declaration in the
base-specifier list, and then the ...."

Note, it says only about direct base classes, nothing about virtual
base
classes.


Yes, this is up to direct base classes. The implicitlt defined
assignment operators would take care of their own bases, I think, but
the OP's excplicitly defined assigment operators didn't do this. My
mistake.

Jonathan



[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Francis Glassborow
Guest





PostPosted: Wed Jan 28, 2004 8:11 pm    Post subject: Re: virtual inheritance and operator= Reply with quote

In message <bv6bcg$okod3$1 (AT) ID-216073 (DOT) news.uni-berlin.de>, Jonathan
Turkanis <technews (AT) kangaroologic (DOT) com> writes
Quote:
Yes, this is up to direct base classes. The implicitlt defined
assignment operators would take care of their own bases, I think, but
the OP's excplicitly defined assigment operators didn't do this. My
mistake.

In effect, once a programmer defines any operator= for a base class s/he
will need to define them all at all levels or tolerate 'reassignment'
for some sub-objects. Unlike copy construction which always does
something for the base classes, copy assignment trusts the programmer to
do everything once the programmer declares an operator=.

--
Francis Glassborow ACCU
Author of 'You Can Do It!' see http://www.spellen.org/youcandoit


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
kanze@gabi-soft.fr
Guest





PostPosted: Wed Jan 28, 2004 8:17 pm    Post subject: Re: virtual inheritance and operator= Reply with quote

"Jonathan Turkanis" <technews (AT) kangaroologic (DOT) com> wrote

Quote:
"Michael Mellor" <news-at- (AT) michaelmellor-dot- (DOT) com> wrote in message
news:bv3j0d$toe$1 (AT) news8 (DOT) svr.pol.co.uk...
Take the following example of virtual inheritance:
#include
struct Base {
Base &operator= ( const Base &a ) {
std::cout << "Basen";
return *this;
}
};

struct DervA : virtual public Base {
DervA &operator= ( const DervA &a ) {
std::cout << "DervAn";
return *this;
}
};

struct DervB : virtual public Base {
DervB &operator= ( const DervB &a ) {
std::cout << "DervBn";
return *this;
}
};

struct Derv2 : public DervA , public DervB {
};

int main ( ) {
Derv2 a, b;
a = b;
}

Visual C++ 7.0 gives:
Base
DervA
DervB

g++ 3.3.1 gives:
DervA
DervB

What is the correct behaviour?

There's no single correct behavior. From 12.8/13:

In this particular case, I think there is.

Quote:
The implicitly-defined copy assignment operator for class X
performs memberwise assignment of its subobjects. ...

You cut a critical part. The order of assignment is strictly defined,
and only the direct bases are directly assigned by the compiler
generated assignment operator. In this particular case, Base is NOT a
direct base of Derv2, and its assignment operator should not be called
by the compiler generated assignment operator of Derv2 (since
presumably, it has been correctly handled in the user defined assignment
operators of the DervA and DervB).

Quote:
It is unspecified whether subobjects representing virtual base
classes are assigned more than once by the implicitly-defined
copy assignment operator. [Example:
struct V { };
struct A : virtual V { };
struct B : virtual V { };
struct C : B, A { };
it is unspecified whether the virtual base class subobject V is
assigned twice by the implicitly-defined
copy assignment operator for C. -end example]

The example is interesting in that none of the classes have user defined
assignment operators. So the compiler has to generate all of the
assignment operators. My interpretation of the text you quote is that
in this case, it is unspecified whether the compiler takes precautions
to avoid double assignment or not.

Quote:
This makes it clear that

Base
DervA
Base
DervB

Not if he has a user defined assignment operator in DervA and DervB.

Quote:
would be an acceptable output, but I don't know of a compiler that
does this. I read the above passage to rule out the g++ 3.3.1
behavior, but I'm not sure. A number of other compilers also behave
this way.

I think that for his particular case, the behavior of g++ is the only
one legal. Consider the following (based on Rob Murray's suggested way
of handling this, in "C++ Strategies and Tactics", if I remember
correctly):

struct VB { VB& operator=( VB& other ) ; } ;

struct L : public virtual VB
{
L& operator=( L const& other )
{
VB::operator=( other ) ;
partialAssign( other ) ;
return *this ;
}
protected:
void partialAssign( L const& other )
{
// assign of our members, uniquely, no assign
// of VB or its members...
}
} ;

struct R : public virtual VB
{
// like L...
} ;

struct D : L, R
{
D& operator=( D const& other )
{
VB::operator=( other ) ;
L::partialAssign( other ) ;
R::partialAssign( other ) ;
// assign of our members...
return *this ;
}
} ;

So far, so good. No implicit, compiler generated assignment operators,
and everything. Now I derive one step further:

struct D2 : D {} ;

What should the compiler generated assignment operator do? If the
assignment operator for Base is to be called from Derv2, above, why
shouldn't the assignment operator for VB be called here, before the one
for D (which will in turn arrange for the assignment operator for VB to
be called exactly once)?

--
James Kanze GABI Software mailto:kanze (AT) gabi-soft (DOT) fr
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Carl Daniel
Guest





PostPosted: Wed Jan 28, 2004 8:42 pm    Post subject: Re: virtual inheritance and operator= Reply with quote

[email]kanze (AT) gabi-soft (DOT) fr[/email] wrote:
Quote:
It's a bug in VC++. Although VC++ is arguably providing the more
useful behavior, the standard requires the behavior of G++.

The Whidbey ("VC8") alpha version of VC++ exhibits the same beahvior as G++.

-cd


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated) All times are GMT
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.