Your code example fails to compile with the online Comeau compiler as well.

Quote:

The compiler error is simply because of Diamond pattern -- duplicate base class?

Yes.

Quote:

Actually from logical point of view, there should be no ambiguity issue.

Yes, but nonetheless there is ambiguity since with non-virtual inheritance there are two distinct Base sub-objects.

02-05-2008

George2

Thanks laserlight,

Quote:

Originally Posted by laserlight

Yes, but nonetheless there is ambiguity since with non-virtual inheritance there are two distinct Base sub-objects.

Why "two distinct Base sub-objects"? I think object instances' different because of data member, common in code (member methods). Since there is no data members, I think they should be no differences. And they should not consume any space -- only data member consumes space and member functions share common code.

regards,
George

02-05-2008

iMalc

It sounds to me like you're thinking of virtual inherritance, which is not what your code snippet uses.

02-05-2008

CornedBee

The language rules of C++ require that there be two distinct Base objects, whether they have data members or not. Furthermore, the language rules require that these two objects have different addresses. Thus, which subobject is cast to very much matters - you get different addresses. Try it out.

Finally, the two objects actually do differ. One points to the "Final through Derived1" vtable, the other to the "Final through Derived2" vtable. This is important if you static_cast the Base pointer to Derived1 or 2, which you're allowed to do (only the correct one) under the C++ rules, if not under COM rules (but the compiler can't know you're doing COM).

02-07-2008

George2

Thanks CornedBee,

Two more comments,

1.

Quote:

Originally Posted by CornedBee

The language rules of C++ require that there be two distinct Base objects, whether they have data members or not. Furthermore, the language rules require that these two objects have different addresses. Thus, which subobject is cast to very much matters - you get different addresses. Try it out.

I have tried they have different address. What makes me confused is sizeof (Base type object) will consume 1 byte. What is the 1 byte for?

I think for a class object instance, only data member should consume memory (address), but in Base, there is no data member, and should not consume any address? But an object instance without taking any memory (address) sounds unbeliveable.

2.

Quote:

Originally Posted by CornedBee

Finally, the two objects actually do differ. One points to the "Final through Derived1" vtable, the other to the "Final through Derived2" vtable. This is important if you static_cast the Base pointer to Derived1 or 2, which you're allowed to do (only the correct one) under the C++ rules, if not under COM rules (but the compiler can't know you're doing COM).

There is no virtual function in my sample class, Base, Derived1, Derived2 and Final. Why do you say there is still a vtable (I think you mean virtual function table)? From debugger, you can not see a _vfptr there.

regards,
George

02-07-2008

laserlight

Quote:

I have tried they have different address. What makes me confused is sizeof (Base type object) will consume 1 byte. What is the 1 byte for?

I think for a class object instance, only data member should consume memory (address), but in Base, there is no data member, and should not consume any address? But an object instance without taking any memory (address) sounds unbeliveable.

Whether the functions are virtual or not, there are two distinct versions of "base" that could be the base pointer you'd convert to - and that's what the compiler is complaining about. There may not be a vtable, but the compiler would have to know WHICH one of the two base objects you mean in the statement to resolve any references to the pointer later on - and this is why it's refusing.

But most importantly: Multiple inheritance is something that is best avoided, particularly if the same base is involved more than once. Just don't do that.

--
Mats

02-07-2008

CornedBee

Quote:

Originally Posted by George2

There is no virtual function in my sample class, Base, Derived1, Derived2 and Final. Why do you say there is still a vtable (I think you mean virtual function table)? From debugger, you can not see a _vfptr there.

Basically, the problem is that you create too many threads, so I confused some of them.

--------------------
Finally, the two objects actually do differ. One points to the "Final through Derived1" vtable, the other to the "Final through Derived2" vtable. This is important if you static_cast the Base pointer to Derived1 or 2, which you're allowed to do (only the correct one) under the C++ rules, if not under COM rules (but the compiler can't know you're doing COM).
--------------------

This is what I said in post #6
--------------------
There is no virtual function in my sample class, Base, Derived1, Derived2 and Final. Why do you say there is still a vtable (I think you mean virtual function table)? From debugger, you can not see a _vfptr there.
--------------------

So, there should not be any reserved vtable or vtable pointer data structure in a class's instance, whose class does not have virtual function at all, right?

Quote:

Originally Posted by matsp

Whether the functions are virtual or not, there are two distinct versions of "base" that could be the base pointer you'd convert to - and that's what the compiler is complaining about. There may not be a vtable, but the compiler would have to know WHICH one of the two base objects you mean in the statement to resolve any references to the pointer later on - and this is why it's refusing.

But most importantly: Multiple inheritance is something that is best avoided, particularly if the same base is involved more than once. Just don't do that.

You're not allowed to cast in COM, except for downcasts (derived->base). You have to use QueryInterface for everything beyond that.

Quote:

So, there should not be any reserved vtable or vtable pointer data structure in a class's instance, whose class does not have virtual function at all, right?

Correct. I just assumed that there was a virtual function, because this thread was such a clear derivative of the thread where you asked about the cast in the COM object implementation.

However, this doesn't change the fact that the standard requires that
1) every object has non-zero size (i.e. sizeof(EmptyClass) > 0) and
2) no two objects of the same type reside at the same address.

In particular, the latter applies to same-type base objects of any given class, too. The Base coming through the Derived1 path may not sit at the same address as the Base coming through the Derived2 path.

02-08-2008

matsp

Rephrasing CornedBee's statement to make it clearer.
The Base coming through the Derived1 path can not sit at the same address as the Base coming through the Derived2 path.

--
Mats

02-08-2008

George2

Thanks CornedBee,

Your reply is great! I have programmed with COM for some time. Actually, I have never seen cast other than downcast. Why in COM we should not upcast anything?

Quote:

Originally Posted by CornedBee

You're not allowed to cast in COM, except for downcasts (derived->base). You have to use QueryInterface for everything beyond that.