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