This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug c++/13881] [3.3 Regression] Allow comparison between unrelated pointer-to-data-members
- From: "smelkov at mph1 dot phys dot spbu dot ru" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 29 Jan 2004 12:26:38 -0000
- Subject: [Bug c++/13881] [3.3 Regression] Allow comparison between unrelated pointer-to-data-members
- References: <20040127101921.13881.smelkov@mph1.phys.spbu.ru>
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
------- Additional Comments From smelkov at mph1 dot phys dot spbu dot ru 2004-01-29 12:26 -------
(In reply to comment #2)
Giovanni,
> You seem confused on the subject. "A C::*" and "B C::*" are totally unrelated
> types. The default conversion could be applied if, e.g., you were to
> compare "int B::*" and "int A::*", because A is an un-ambigous non-virtual
> accessible base class of B, so the latter pointer can be converted to the
> former type.
I agree, that my writing was somewhat mislieading. I'll try to clarify this:
A and B is related types (A is base of B), hence B* can be casted to A*.
As to 'A C::*' and 'B C::*' they are pointers to A & B objects in specific scope (C class) --- i
think they are related too.
for example:
struct C {
A a;
B b;
};
C* pc;
A* pa;
B* pb; // B inherits from A
pa = pb; // ok
*pa=... // ok, dereference to B::A
// I used to think that binding memptr has the same semantics as dereferencing plain pointer of
// the same type, i.e. [see some_A_method() call below]
C c;
A C::* mem_pa;
B C::* mem_pb;
pa = &c.a; // ok
pb = &c.b; // ok
pa = &c.b; // !!! this is also correct!!!
mem_pa = &C::a; // ok
mem_pb = &C::b; // ok
mem_pa = &C::b; // ?wrong?
// but i want to do:
pa->some_A_method();
(c.*mem_pa).some_A_method();
// some_A_method() may be virtual thus calling B::some_A_method instead.
//
// with member pointers i can't do that.
-----
I digged the subject a bit, here is my understanding:
All i'm saying about is possible, but is not implemented for now.
The main reason for this is multiple inheritance (i wouldn't say about virtual and others),
hence for member pointer it is necessary to store some kind of offset (addres for plain
functions, vtable offset for virtual functions, class offset for data members, ets) and this delta
(for casting).
for pointers to member functions this is all done (sizeof(int (C::*)() on my machine is 8, the
structure contain __offset and __delta),
for pointers to data members it is not implemented (sizeof(int C::*) = 4)
> Notice the direction that the conversion follows is the opposite
> of that of normal pointers: in fact, every member of A is also a member of B,
> so every "int A::*" is also a valid "int B::*". Instead, if you have a
> generic "int B::*" you can't say for sure that it points to a member of A.
>
> Look into [conv.mem]/2 in the ISO C++ Standard for further clarifications.
>
>
> 3.4/mainline follows the right behaviour, while the bug is still present on the
> 3.3 branch. Maybe we can pinpoint and backport the patch that fixed it.
>
Thanks,
Kirill.
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=13881