polfer@b11.ingr.com (? Polfer) (09/20/90)
While porting some code to an ANSI compiler (NOT porting to ANSI), I received an error with code similar to the following: int (**command)(); ... *command = NULL; The warning was: "Type `void *' is not assignment compatible with type `int (*)()'." The compiler is not in full ANSI mode (we must keep using a non ANSI compiler on another platform), so prototyping is NOT being used. It turns out that Metaware High C defines NULL in stdio.h as "(void *)0". This gives a little bit more error checking than just using "0". My question is why the above code errors out. "*command" is a pointer to a function which returns int, but it is still a pointer. I understand that ANSI does not guarantee that pointers to different types will have the same internal repesentations, but isn't a "void *" supposed to be assignment compatible with ALL pointers? The fix is to use "*command = (int (*)())0;" or just plain "*command = 0;", neither of which yield errors. Could this be because "0" is considered the generic NULL pointer value while the explicit cast (void *) fouls the assignment? Any ideas would be appreciated! ----- Dan Polfer uunet!ingr!b11!dap!dan (UUCP) b11!dap!dan@ingr.com (Internet)
chris@mimsy.umd.edu (Chris Torek) (09/20/90)
In article <8770@b11.ingr.com> polfer@b11.ingr.com (? Polfer) writes: >... "Type `void *' is not assignment compatible with type `int (*)()'." >The compiler is not in full ANSI mode ... [and] Metaware High C >defines NULL in stdio.h as "(void *)0". The value ((void *)0) is a generic nil pointer, as well as being a particular specific nil pointer, and any compiler that believes it is not suitable in an (int (*)()) context is buggy (at least if the compiler claims ANSI conformance). Personally, I think defining NULL as (void *)0 is foolishness: if you want your compiler to provide complete error checking, you should define it as `__nil' and make __nil a keyword. Using (void *)0 fixes a few specific problems, but leaves others unfixed and unfixable. -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 405 2750) Domain: chris@cs.umd.edu Path: uunet!mimsy!chris
karl@haddock.ima.isc.com (Karl Heuer) (09/20/90)
In article <8770@b11.ingr.com> polfer@b11.ingr.com (? Polfer) writes: > int (**command)(); > *command = NULL; > "Type `void *' is not assignment compatible with type `int (*)()'." >isn't a "void *" supposed to be assignment compatible with ALL pointers? No, it's compatible with all *data* pointers. Function pointers need not fit in a `void *'. But (as Chris Torek already pointed out), a null pointer constant is a special case. Your compiler has a bug in that it apparently fails to recognize the `(void *)0' form as a null pointer constant. Karl W. Z. Heuer (karl@kelp.ima.isc.com or ima!kelp!karl), The Walking Lint
henry@zoo.toronto.edu (Henry Spencer) (09/23/90)
In article <26628@mimsy.umd.edu> chris@mimsy.umd.edu (Chris Torek) writes: >Personally, I think defining NULL as (void *)0 is foolishness: if you >want your compiler to provide complete error checking, you should define >it as `__nil' and make __nil a keyword. Using (void *)0 fixes a few >specific problems, but leaves others unfixed and unfixable. Actually, the Rationale for ANSI C makes it clear that error checking had nothing to do with making `(void *)0' an official null pointer. The motive was to provide for a NULL of the same size as most pointers -- thereby minimizing breakage of old defective code -- on machines where there is no integer type of the right size. Minimizing breakage is also the reason why (e.g.) `0L' is also a legal NULL, for machines where pointers are the size of longs rather than ints. -- TCP/IP: handling tomorrow's loads today| Henry Spencer at U of Toronto Zoology OSI: handling yesterday's loads someday| henry@zoo.toronto.edu utzoo!henry