Function pointer syntax peculiarity

Ken Arnold%CGL arnold at ucsfcgl.UUCP
Wed Nov 28 05:22:08 AEST 1984


Looking at the code for qsort(), I came across the following
peculiarity in the syntax and semantics of function pointers.  It seems
that "(*cfunc)()" and "cfunc()" are both equivalent uses of a pointer
to a function "cfunc".  qsort takes, as it's fourth parameter, a
pointer to a function.  Below is a piece of sample pseudo code

	extern int	cmp();

	...
	qsort(<base>, <# of elements>, <width of an element>, cmp);
	...

The qsort declaration is

	qsort(base, nel, width, cfunc)
	char	*base;
	int	nel, width;
	int	(*cfunc)(); { ... }

I have used pointers to functions, and the way I use them is

	(*cfunc)(...);	/* call this syntax 1 */

However, qsort() uses it like this:

	cfunc(...);	/* call this syntax 2 */

which seems to work.  I have tested the code on our 4.2bsd C compiler
(a version of PCC) and both usages generate the same code, and neither
gives a warning message.  Now, having "*f" and "f" mean the same thing
doesn't fit into the normal meaning of unary "*", so which is right?

This sends me scurrying to K&R, which uses syntax 1 in all it's
examples.  I have also always used this sytax.  But after thinking
about it (always a dangerous thing to do :->), it seems to me that
syntax 2 is more consistent with the semantics of the thing.

Consider how you declare that cfunc() is a function, and how you get
the pointer out of that declaration.  The following is typical
(equivalent code for an array is presented on the side for reasons
which will be clear below):

	int	cfunc();		int	integers[12];

		...				...
		some_func(cfunc);		another_func(integers)
		...				...

	some_func(function)		another_func(array)
	int	(*function)();		int	*array;
	{				{
		...				...
		(*function)(10);		i = array[10];
		...				...
	}				}

The name of the function "cfunc" becomes the address of the function in
the same way that the name of the array "integers" becomes the address
of the array.  So why, when you use it, do you have to specify taking
the contents of the variable "function", but not have to do the same
with "array"?

The parallel of these two uses of pointers seems strong.  To get the
address, you use the name.  In the case of the array, the "[10]"
indicates an indirection off of the primary expression, either in the
case of "array[10]" or "integers[10]".  But in the case of arrays, for
some reason, if the primary expression is a function name, the "(10)"
indicates "indirection" from the address, but if the primary expression
is a variable name it does not.

I'm curious what other people think about this.  The current situation
in which BOTH syntax 1 and 2 are allowed concurrently is certainly
confusing and nonsensical.  I would tend to support a change to syntax
2, with syntax 1 usage generating a warning, as the "=+" operators have
done.

It is possible this has been dealt with in the proposed C standard,
which I have yet to see more than a summary of.  If it is, what is the
solution?  While we're at it, where can people get a copy of The Real
Thing?

		Ken Arnold



More information about the Comp.lang.c mailing list