[comp.lang.c] double pointer to function

stergios@athsys.uucp (Stergios Marinopoulos) (08/07/88)

Can anyone  figure  out why  the  following   code  does not   compile
correctly?  The first ?/: pair makes cc (sun  3.4) complain, while the
second one does not.  The only difference between the two is where the
double pointer to functions  get  dereferenced.  Don't  think for    a
second I write   code like this, it's  the  ouput of  a C++ translator
considerably simplified and cleaned up.


struct A { int (**A_tablePtr )(); } ;

void A_c ();
void A_d () ;

static int (*A__vtbl[])() = { (int(*)()) A_d , 0 };


typedef void (**PMF )();

extern int function1() ;
extern int function2() ;

void A_c (this , pmf )
struct A *this ;
void *pmf ;
{

  extern int flag ;

  /* code ccxx produces and error message cc spits out */
  /* warning: illegal pointer combination: illegal types in : */
  (*(
     (void (*)()) ( flag ?
		   (*((void (**)())pmf ))
		   :
		   (this -> A_tablePtr [(((unsigned int )(*(((void (**)())pmf ))))) - 1])
		   )
     )
   )
    ( this ) ;


  /* my hack to get it compiling */
  /* no problems */

  (**(
     (void (**)()) ( flag ?
		   ((void (**)())pmf )
		   :
		   (void (**)())(&(this -> A_tablePtr [(((unsigned int )(*(((void (**)())pmf ))))) - 1]))
		   )
     )
   )
    ( this ) ;
  
  
}



stergios marinopoulos
sun!athsys!stergios

chris@mimsy.UUCP (Chris Torek) (08/08/88)

In article <107@cyclopes.UUCP> stergios@athsys.uucp (Stergios Marinopoulos)
writes:
>Can anyone figure out why the following code does not compile
>correctly?  The first ?/: pair makes cc (sun 3.4) complain ....
>[(This is] the ouput of a C++ translator [).]

Sun's compiler is correct to complain.  Retaining only the relevant
code, and deleting various unnecessary parentheses:

>struct A { int (**A_tablePtr)(); };
>  struct A *this ;
>  void *pmf ;
>  extern int flag ;
>  flag ? *(void (**)())pmf :
>	  this->A_tablePtr[(unsigned int)*(void (**)())pmf) - 1]

Examine the types of the objects on each side of the `:':

	*(void (**)())pmf   =>
	    cast pmf to
		pointer to pointer to function returning void
	    then indirect, so type is
		pointer to function returning void

	this->A_tablePtr[ <horrible unsigned-int-valued expression> ]   =>
	    subscript (indirect) an object of type
		pointer to pointer to function returning int
	    so type is
		pointer to function returning int

Both are pointers to functions, but one returns void, the other int.
For the expressions to be compatible, either the ?: line must read

	flag ? *(int (**)())pmf : <original rhs>

or the delcaration of `struct A' must read

	struct A { void (**A_tablePtr)(); };
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris@mimsy.umd.edu	Path:	uunet!mimsy!chris

leo@philmds.UUCP (Leo de Wit) (08/08/88)

In article <107@cyclopes.UUCP> stergios@athsys.UUCP (Stergios Marinopoulos) writes:
|Can anyone  figure  out why  the  following   code  does not   compile
|correctly?  The first ?/: pair makes cc (sun  3.4) complain, while the
|second one does not.  The only difference between the two is where the
|double pointer to functions  get  dereferenced.  Don't  think for    a

It is not the only difference. The second uses a cast for the second
operand (the one after :) so that the types of both parts of the ?:
expression are the same.

|second I write   code like this, it's  the  ouput of  a C++ translator
|considerably simplified and cleaned up.
|
|
|struct A { int (**A_tablePtr )(); } ;

   [stuff deleted]......

|void A_c (this , pmf )
|struct A *this ;
|void *pmf ;
|{
|
|  extern int flag ;
|
|  /* code ccxx produces and error message cc spits out */
|  /* warning: illegal pointer combination: illegal types in : */
|  (*(
|     (void (*)()) ( flag ?
|		   (*((void (**)())pmf ))
|		   :
|		   (this -> A_tablePtr [(((unsigned int )(*(((void (**)())pmf ))))) - 1])
|		   )
|     )
|   )
|    ( this ) ;

The type of the first part of the ?: expression is different from the type
of the second part (no, I don't want to spell it out 8-), so I think cc
is correct to complain (see also K&R 7.13 about the conditional operator).

In the second part (the 'hack') both parts are cast to (void (**)()) so
there is no problem here.

      Leo.