[comp.sys.mac.programmer] Function pointers and lack of type conversion in Think C

hanche@imf.unit.no (Harald Hanche-Olsen) (11/03/90)

Executive summary:  Bug in Think C -- If a function is called via a
function pointer then automatic type conversion of its args does not
take place.

Consider the following file:
----------------
typedef void (*funpoint)(long, long);
void fun_a(long,long);

main()
{
	funpoint fun;
	int i=1, j=2;
	fun=fun_a;
	(*fun)(i,j);
	fun_a(i,j);
}

void fun_a(long a, long b)
{
	printf("fun_a: %08lx %08lx\n", a, b);
}
----------------
This produces the two lines of output:

fun_a: 00010002 00020001   <<== WRONG  (int args are not converted to longs)
fun_a: 00000001 00000002   <<== Right

Think C has no excuse for this, as the fun pointer has a type that
allows the compiler to determine the type of the arguments.

This caused lots of interesting crashes for me, as I was porting a
U**x program that likes to play with function pointers.  Comments?

- Harald Hanche-Olsen <hanche@imf.unit.no>
  Division of Mathematical Sciences
  The Norwegian Institute of Technology
  N-7034 Trondheim, NORWAY

pratt@boulder.Colorado.EDU (Jonathan Pratt) (11/03/90)

In article <HANCHE.90Nov2180656@hufsa.imf.unit.no> hanche@imf.unit.no (Harald Hanche-Olsen) writes:
>Executive summary:  Bug in Think C -- If a function is called via a
>function pointer then automatic type conversion of its args does not
>take place.
>

Not a bug, but a missing feature (that would be nice to have).  If you'd
read the TC4 manual, language reference, page 441, you'd see:

"Prototype arguments which are not associated with a named function are
permitted, but not honored.  For example:

int (*fn)(int n);		/* prototype ignored */		"

Jonathan

/* Jonathan Pratt          Internet: pratt@boulder.colorado.edu     *
 * Campus Box 525              uucp: ..!{ncar|nbires}!boulder!pratt *
 * University of Colorado                                           *
 * Boulder, CO 80309          Phone: (303) 492-4293                 */

hanche@imf.unit.no (Harald Hanche-Olsen) (11/04/90)

In article <29170@boulder.Colorado.EDU> pratt@boulder.Colorado.EDU (Jonathan Pratt) writes:

   Not a bug, but a missing feature (that would be nice to have).  If you'd
   read the TC4 manual, language reference, page 441, you'd see:

   "Prototype arguments which are not associated with a named function are
   permitted, but not honored.  For example:

   int (*fn)(int n);		/* prototype ignored */		"

Ahh, yes, always RTFM first.  I looked but did not find the above
reference.  All right, so it's not a bug but just another gotcha.
Meanwhile, is anyone out there knowledgeable enough to tell us whether
a true ANSI compiler must behave the way I had believed it would with
respect to function pointers?  If not then perhaps I ought to make a
guest appearance in comp.lang.c or some such place to ask the question
there.

Thanks for finding that quote for me.

- Harald Hanche-Olsen <hanche@imf.unit.no>
  Division of Mathematical Sciences
  The Norwegian Institute of Technology
  N-7034 Trondheim, NORWAY

beard@ux5.lbl.gov (Patrick C Beard) (11/23/90)

In article <HANCHE.90Nov4142933@hufsa.imf.unit.no> hanche@imf.unit.no (Harald Hanche-Olsen) writes:
#In article <29170@boulder.Colorado.EDU> pratt@boulder.Colorado.EDU (Jonathan Pratt) writes:
#
#   Not a bug, but a missing feature (that would be nice to have).  If you'd
#   read the TC4 manual, language reference, page 441, you'd see:
#
#   "Prototype arguments which are not associated with a named function are
#   permitted, but not honored.  For example:
#
#   int (*fn)(int n);		/* prototype ignored */		"
#
#Ahh, yes, always RTFM first.  I looked but did not find the above
#reference.  All right, so it's not a bug but just another gotcha.
#Meanwhile, is anyone out there knowledgeable enough to tell us whether
#a true ANSI compiler must behave the way I had believed it would with
#respect to function pointers?  If not then perhaps I ought to make a
#guest appearance in comp.lang.c or some such place to ask the question
#there.

I don't know if ANSI C compilers have to support this; however, MPW C++
and I believe all C++ compilers handle this correctly.  In fact, MPW C++
even calls function pointers of type pascal with the correct calling
conventions!

pascal void (*fn)(short x, short y); // pushes x, then y.

I assume MPW C supports this as well.
--
-------------------------------------------------------------------------------
-  Patrick Beard, Macintosh Programmer                        (beard@lbl.gov) -
-  Berkeley Systems, Inc.  ".......<dead air>.......Good day!" - Paul Harvey  -
-------------------------------------------------------------------------------