[net.lang.c] Shouldn't this work?

keithr@zeus.UUCP (Keith Rule) (08/16/84)

[bug food]


	The following program fragment demonstates a problem with
	"void". I wish to build a jump table to "void" functions,
	however this program fragment, which defines the jump table,
        doesn't compile. If I replace all the "void"s with "int"s the 
	fragment compiles without any problems.

 
	1	#include <stdio.h>
	2
	3	typedef struct Builtin {
	4		char *name;
	5		void (*func)();
	6	} BUILTIN;
	7
	8	extern void beep();
	9
	10	BUILTIN builtins[] = {
	11		{"beep",		beep},
	12		{(char *) NULL,		(void (*)()) NULL}
	13	};

	Output from lint. The C complier also produces the first 
	error message.

	tmp.c:
	tmp.c(11): operands of = have incompatible types
	tmp.c(11): illegal initialization
	builtins defined( tmp.c(10) ), but never used

	Would someone please tell me what I'm doing wrong. 
	I'm stumped.

	Thanks in Advance,

	Keith Rule

	tektronix!teklds!keithr

gwyn@BRL-VLD.ARPA@sri-unix.UUCP (08/24/84)

From:      Doug Gwyn (VLD/VMB) <gwyn@BRL-VLD.ARPA>

There is nothing wrong with your example.  I suspect you are using
an old (pre-UNIX System V) portable C compiler (e.g. UNIX System III
or 4.[12]BSD); these do not correctly handle pointers to void-
valued functions.  Lint is built from PCC sources and has the same
problem.  Starting with Release 1.0 of UNIX System V, the portable
C compiler and lint handled this correctly.  I tried the Gould UTX
C compiler on this very thing and it is better than usual, but not
yet perfect.

I believe that the reason that the signal() function has been
misdefined for so long is that the compilers could not handle
the correct type declaration.  I urge the UNIX developers to FIX
THIS now that their compilers are working:

extern void	(*signal())();
#define	SIG_DFL	(void (*)())0
#define	SIG_IGN	(void (*)())1

west@sdcsla.UUCP (Larry West) (08/25/84)

Yes, it should, and it probably is a problem with the 4.2bsd compiler.
Try this fragment for fun:

	extern void *beep();
	void (*funk)() = (void (*)()) beep;
	main () {}

When used in this skeleton form, "cc" ("ld") only complained that "beep"
was undefined, and "lint" only said that "funk" was defined but never used.

[The original article had declared "extern void beep()", and used it
 in an equivalent structure initialization].

I don't know what "void *" >means<, nor why it is type-compatible in this
case, but there it is.   Example tried on Sun-2 and Vax.   Long live 4.2bsd.

	-- Larry West, UC San Diego, Institute for Cognitive Science
	-- decvax!ittvax!dcdwest!sdcsvax!sdcsla!west
	-- ucbvax!sdcsvax!sdcsla!west
	-- west@NPRDC

jim@ism780b.UUCP (08/27/84)

#R:zeus:-34700:ism780b:25500020:000:104
ism780b!jim    Aug 25 15:45:00 1984

It's a bug in the C compiler.  They fixed it in System V.

-- Jim Balter, INTERACTIVE Systems (ima!jim)

ron@brl-tgr.ARPA (Ron Natalie <ron>) (08/28/84)

You're not doing anything wrong.  A bug in the older versions of
the compiler doesn't allow pointers to functions returning void.

Bugs, Mr Rico.  Zillions of 'em.

-Ron

berry@zinfandel.UUCP (Berry Kercheval) (08/29/84)

I must be dumb.  Would some please explain to me in words of 
one syllable what in h**l a pointer to void is good for?  Is REALLY
just a pointer to data of unspecified type?

-- 
Berry Kercheval		Zehntel Inc.	(ihnp4!zehntel!zinfandel!berry)
(415)932-6900

martillo@mit-athena.ARPA (Joaquim Martillo) (09/03/84)

Often times it might be desirable to pass the address of a function
which returns no value (a void function) to another function.  Therefore
the declaration:

	void (* f)();

could be usefual as a definition of a function argument.

gwyn@brl-tgr.UUCP (09/04/84)

In currently available C implementations, (void *) data are illegal.
However, (void (*)()) data are legal and quite useful (too bad they
break older versions of PCC).

The proposed use of (void *) in the future C standard is as a generic
pointer, such as malloc(3) should return; one that can be cast into
a pointer to any other datum.  To date this r^ole has been served
by (char *), although that was not the intended use of (char *) and
one desires a separation of these types (for "lint" etc.).