Topic: Is this fragment legal?
Author: maxtal@physics.su.OZ.AU (John Max Skaller)
Date: Fri, 10 Jun 1994 13:15:05 GMT Raw View
>> Sure. Because your code is illigal. You cannot assign a pointer
>> to member function of a derived class to a base class pointer.
>
>However, you can cast between them, which is what the fragment does. From
>the January WP:
>
>7 A pointer to member of class A of type T1 may be explicitly converted | |
> to a pointer to member of class B of type T2 when class A and class |
> B are either the same class or one is unambiguously derived from |
> the other (4.6), and the types T1 and T2 are the same. |
>
>Jason
Be careful quoting the WP. It is not entirely to be trusted.
The clause above is meaningless because it doesnt say what you
can DO with the resultant pointer to member. After all the result
of the cast may be rubbish since there is no such member of a Base.
--
JOHN (MAX) SKALLER, INTERNET:maxtal@suphys.physics.su.oz.au
Maxtal Pty Ltd, CSERVE:10236.1703
6 MacKay St ASHFIELD, Mem: SA IT/9/22,SC22/WG21
NSW 2131, AUSTRALIA
Author: jason@cygnus.com (Jason Merrill)
Date: Fri, 10 Jun 1994 19:43:25 GMT Raw View
>>>>> John Max Skaller <maxtal@physics.su.OZ.AU> writes:
> Be careful quoting the WP. It is not entirely to be trusted.
> The clause above is meaningless because it doesnt say what you
> can DO with the resultant pointer to member. After all the result
> of the cast may be rubbish since there is no such member of a Base.
True. But then I wasn't trying to establish that the resultant pointer to
member was useful, simply that the code given was well-formed. Subsequent
use of the ptm may be undefined.
Jason
Author: jk@zarniwoop.pc-labor.uni-bremen.de (Jens Kuespert)
Date: 09 Jun 1994 13:35:03 GMT Raw View
Hi!
I came across the following code-fragment which compiles fine with for
following compilers
- BCC 1.0 for OS/2;
- BCC 3.1 for DOS;
- gcc 1.39;
- and I think gcc 2.3.2 can't check this now
The only compiler I know which refuses this code is gcc 2.5.8.
Here is the code in question:
struct A {
long a() { return 0; }
};
struct B: public A {
long b() { return 1; }
};
typedef long (A::*foo)();
int main()
{
foo tt;
tt=A::a;
tt=(foo)B::b; // here come's the error!
}
Any ideas why gcc 2.5.8 rejects this?
Thanks!
--
-- Jens --
Author: kocher@us-es.sel.de (Hartmut Kocher)
Date: Thu, 9 Jun 94 15:05:54 GMT Raw View
In article <JK.94Jun9153506@zarniwoop.pc-labor.uni-bremen.de>, jk@zarniwoop.pc-labor.uni-bremen.de (Jens Kuespert) writes:
>
> Hi!
>
> I came across the following code-fragment which compiles fine with for
> following compilers
>
> - BCC 1.0 for OS/2;
> - BCC 3.1 for DOS;
> - gcc 1.39;
> - and I think gcc 2.3.2 can't check this now
>
> The only compiler I know which refuses this code is gcc 2.5.8.
>
> Here is the code in question:
>
> struct A {
> long a() { return 0; }
> };
>
> struct B: public A {
> long b() { return 1; }
> };
>
> typedef long (A::*foo)();
>
> int main()
> {
> foo tt;
>
> tt=A::a;
> tt=(foo)B::b; // here come's the error!
> }
>
>
> Any ideas why gcc 2.5.8 rejects this?
Sure. Because your code is illigal. You cannot assign a pointer
to member function of a derived class to a base class pointer.
Think about it for a minute! If you were allowed to set tt to
B::b, and you would use tt with an object of class A (that has
no b() member function!), what would happen?
See ARM for more details.
Get rid of your other dated compilers.
>
> Thanks!
>
> --
>
> -- Jens --
--
+==============================|==============================+
| Hartmut Kocher | |
| Technical Consultant | All opinions expressed here |
| Rational GmbH | are my own. |
| Rosenstrasse 7 | |
| 82049 Pullach im Isartal | I know you guessed it, |
| Germany | but it keeps my lawyer happy.|
| Email: hwk@rational.com | |
+==============================|==============================+
Author: pete@genghis.interbase.borland.com (Pete Becker)
Date: Thu, 9 Jun 1994 21:59:32 GMT Raw View
In article <JK.94Jun9153506@zarniwoop.pc-labor.uni-bremen.de>,
Jens Kuespert <jk@zarniwoop.pc-labor.uni-bremen.de> wrote:
>
>Hi!
>
>I came across the following code-fragment which compiles fine with for
>following compilers
>
>- BCC 1.0 for OS/2;
>- BCC 3.1 for DOS;
>- gcc 1.39;
>- and I think gcc 2.3.2 can't check this now
>
>The only compiler I know which refuses this code is gcc 2.5.8.
>
>Here is the code in question:
>
>struct A {
> long a() { return 0; }
>};
>
>struct B: public A {
> long b() { return 1; }
>};
>
>typedef long (A::*foo)();
>
>int main()
>{
> foo tt;
>
> tt=A::a;
> tt=(foo)B::b; // here come's the error!
>}
>
>
The ANSI/ISO working paper requires an '&' when you take the address
of a member function. BC doesn't enforce this in non-ANSI mode (that is, if
you don't specify -A on the command line), mostly so that our users can
compile MFC code, which relies on this undocumented non-standard Microsoft
language extension.
-- Pete
Author: pete@genghis.interbase.borland.com (Pete Becker)
Date: Thu, 9 Jun 1994 22:02:09 GMT Raw View
In article <1994Jun9.150554.28821@lts.sel.alcatel.de>,
Hartmut Kocher <kocher@us-es.sel.de> wrote:
>In article <JK.94Jun9153506@zarniwoop.pc-labor.uni-bremen.de>, jk@zarniwoop.pc-labor.uni-bremen.de (Jens Kuespert) writes:
>>
>> Hi!
>>
>> I came across the following code-fragment which compiles fine with for
>> following compilers
>>
>> - BCC 1.0 for OS/2;
>> - BCC 3.1 for DOS;
>> - gcc 1.39;
>> - and I think gcc 2.3.2 can't check this now
>>
>> The only compiler I know which refuses this code is gcc 2.5.8.
>>
>> Here is the code in question:
>>
>> struct A {
>> long a() { return 0; }
>> };
>>
>> struct B: public A {
>> long b() { return 1; }
>> };
>>
>> typedef long (A::*foo)();
>>
>> int main()
>> {
>> foo tt;
>>
>> tt=A::a;
>> tt=(foo)B::b; // here come's the error!
>> }
>>
>>
>> Any ideas why gcc 2.5.8 rejects this?
>
>Sure. Because your code is illigal. You cannot assign a pointer
>to member function of a derived class to a base class pointer.
>Think about it for a minute! If you were allowed to set tt to
>B::b, and you would use tt with an object of class A (that has
>no b() member function!), what would happen?
>
No, that's not the problem. You are allowed to explicitly convert
a pointer-to-member of a derived class to a pointer-to-member of a base class,
which is what that cast does. The problem is the missing '&'. The correct line
is this:
tt = (foo)&B::b;
-- Pete
Author: jason@cygnus.com (Jason Merrill)
Date: Thu, 9 Jun 1994 21:48:22 GMT Raw View
>>>>> Jens Kuespert <jk@zarniwoop.pc-labor.uni-bremen.de> writes:
> Any ideas why gcc 2.5.8 rejects this?
Because it gets pointers to member functions confused with structures in
some places. This bug will be fixed in 2.6.0.
Jason
Author: jason@cygnus.com (Jason Merrill)
Date: Thu, 9 Jun 1994 21:50:34 GMT Raw View
>>>>> Hartmut Kocher <kocher@us-es.sel.de> writes:
> Sure. Because your code is illigal. You cannot assign a pointer
> to member function of a derived class to a base class pointer.
However, you can cast between them, which is what the fragment does. From
the January WP:
7 A pointer to member of class A of type T1 may be explicitly converted | |
to a pointer to member of class B of type T2 when class A and class |
B are either the same class or one is unambiguously derived from |
the other (4.6), and the types T1 and T2 are the same. |
Jason