Casting void - int question

Tom Stockfisch tps at sdchem.UUCP
Wed Oct 15 12:44:20 AEST 1986


In article <26 at orion.UUCP> heins at orion.UUCP (Michael T. Heins) writes:
>
>int fna() { }
>
>void fnb() { }
>
>int (*array[32])();
>main() {
>    array[0] = fna;
>    array[1] = fnb; /* This won't work as-is. */
>}
>
>I have tried things like
>	array[1] = (int (*)())fnb;
>but this generates the message "operands of CAST have incompatible types".

The compiler rightly complains because
	void (*)()
could conceivably be larger than 
	int (*)()
on some wierd machine.  You should use a union, e.g.:

	union int_or_void_func {
		int	(*int_func)();
		void	(*void_func)();
	}	array[32];

	main()
	{
		array[0].int_func =	fna;
		array[1].void_func =	fnb;
	}

The above is the much preferred way to do this.  However,
if you want to initialize "array[]", you currently can't use a union (ANSI
standard may change this).  Then the portable way to do this is
	
	int	fna();
	void	fnb();

	char	*array[32] = {
		(char *)fna,
		(char *)fnb
	};

	main()
	{
		( *(int (*)())array[0] )();	/* call fna */
		( *(int (*)())array[1] )();	/* call fnb */
	}

If this won't work on some machines, I would appreciate hearing an explanation
from some guru.
A disadvantage of this method, besides ugliness, is that lint gives the
complaint
	questionable conversion of function pointer
for each element of array that you initialize, and each call as well.  In
any application where I use this method I wind up creating a lint filter
such as
	grep -v 'questionable conversion of function pointer'
and use it on all lint output.
-- 

-- Tom Stockfisch, UCSD Chemistry



More information about the Comp.lang.c mailing list