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!keithrgwyn@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@NPRDCjim@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.).