[comp.lang.c++] cfront/c++ problem

joemac@apple.UUCP (Joe MacDougald) (09/10/87)

cfront dies with an bus error when compiling the following:

struct T {
	int f;
		T() { f = 1; }	// constructor
	virtual int getf();
};

int T::getf()
{
	return f;
}

typedef int (T::*PROC)();	// S 5.4.5  p. 154 : pointer to member function
				// of T taking no args, returning int.
main()
{
	T t;			// t is an instance of T

	PROC p = &T::getf;	// p points to T's member function getf

/*ERROR*/ int r = (t.*p)();	// call function pointed at by p, assign to r
}

The error occurs at the point of invocation of the function pointed to by p.

If the member function is not declared virtual there are no problems in 
compilation or execution.

Nowhere does Stroustrup mention pointers to virtual methods, so I wonder if it
is a valid operation.  If it is invalid, cfront needs to exit more gracefully.

Has anyone used this aspect of the language?

Any comments would be greatly appreciated.
	
	Thanks,
		Joe

mikem@otc.oz (Mike Mowbray) (09/11/87)

In article <6191@apple.UUCP>, joemac@apple.UUCP (Joe MacDougald) says:

> struct T {  /* ........ */ };
> 
> int T::getf()  { return f; }
> 
> typedef int (T::*PROC)();	// S 5.4.5  p. 154 : pointer to member fn
> 				// of T taking no args, returning int.
> main()
> {
> 	T t;			// t is an instance of T
> 	PROC p = &T::getf;	// p points to T's member function getf
> 
> /*ERROR*/ int r = (t.*p)();	// call function pointed at by p, assign to r
> }
> 
> Nowhere does Stroustrup mention pointers to virtual methods, so I wonder
> if it is a valid operation.

It is indeed a valid operation. In fact, cfront is quite smart. It will
actually find the right function when dereferenced even though it's virtual
(which is non-trivial if you think about it).

I understand the problem is that the current grammar has problems with the
typedef. If it is simply replaced, things work. E.g:

    int (T::*p)();

    main()
    {
	T  t;
	int r = (t.*p)();
    }

is okay. Trouble is that the declaration of p has to be outside the function,
which is a pain. If it's inside, there's an (incorrect) syntax error. I
understand that the next release will address this bug.

			Mike Mowbray
		    Systems Development
			|||| OTC ||

		    ACSnet:  mikem@otc.oz   UUCP:  {uunet,mcvax}!otc.oz!mikem 

mitsu@well.UUCP (Mitsuharu Hadeishi) (09/12/87)

In article <253@otc.oz> mikem@otc.oz (Mike Mowbray) writes:
>In article <6191@apple.UUCP>, joemac@apple.UUCP (Joe MacDougald) says:
>> struct T {  /* ........ */ };
>> 
>> int T::getf()  { return f; }
>> 
>> typedef int (T::*PROC)();	// S 5.4.5  p. 154 : pointer to member fn
>> 				// of T taking no args, returning int.
>> main()
>> {
>> 	T t;			// t is an instance of T
>> 	PROC p = &T::getf;	// p points to T's member function getf
>> 
>> /*ERROR*/ int r = (t.*p)();	// call function pointed at by p, assign to r
>> }
>> 

	It seems to be that the correct syntax should be:

	PROC p = T::getf;

	Is that not right?  However, the preprocessor should have gronked
there, not later (type mismatch).
				-Mitsu
				 CDI Research & Development
				 Electronic Arts

This line is for news
This line is for news
This line is for news
This line is for news
Eat this line, sucker!

mikem@otc.oz (Mike Mowbray) (09/14/87)

In article <3938@well.UUCP>, mitsu@well.UUCP (Mitsuharu Hadeishi) says:

> 	It seems to be that the correct syntax should be:
> 
> 	PROC p = T::getf;	[ I.e: not PROC p = &T::getf; ]
> 
> 	Is that not right?

In the 1.1 release notes it clearly indicates that the `&' is required, at
least that's how I read it. It also seems logical.

			Mike Mowbray
		    Systems Development
			|||| OTC ||

		    ACSnet:  mikem@otc.oz
		      UUCP:  {uunet,mcvax}!otc.oz!mikem 
		     Phone:  (02) 287-4104
		     Snail:  GPO Box 7000, Sydney 2001, Australia