bxpfac@umiami.ir.miami.edu (05/21/91)
As the subject heading says, is there a NULL pointer to functions?
The program shown below when compiled with gcc generated
the following message:
In function foo:
warning: ANSI C forbids comparison of `void *' with function pointer
/*-- Program --*/
#define NULL ((void *) 0)
void foo (void (*fun) (void))
{
if (fun != NULL) /* Line with the warning. */
fun ();
}
Thanks for any suggestions to fix this.
Bimal / devebw9f@miavax.ir.miami.edu
bxpfac@umiami.ir.miami.edu (05/24/91)
I am not sure if this go posted the first time. Second try!
As the subject heading says, is there a NULL pointer to functions?
The program shown below when compiled with gcc generated
the following message:
In function foo:
warning: ANSI C forbids comparison of `void *' with function pointer
/*-- Program --*/
#define NULL ((void *) 0)
void foo (void (*fun) (void))
{
if (fun != NULL) /* Line with the warning. */
fun ();
}
Thanks for any suggestions to fix this.
Bimal / devebw9f@miavax.ir.miami.edu
bhoughto@pima.intel.com (Blair P. Houghton) (05/26/91)
In article <1991May21.125639.10052@umiami.ir.miami.edu> devebw9f@miavax.ir.miami.edu writes: >As the subject heading says, is there a NULL pointer to functions? Yes. >#define NULL ((void *) 0) > >void foo (void (*fun) (void)) >{ > if (fun != NULL) /* Line with the warning. */ > fun (); >} [...] >when compiled with gcc generated the following message: No, when compiled with (at least) 'gcc -ansi -pedantic', it generates this message. I almost missed it by leaving out the '-pedantic'... >In function foo: >warning: ANSI C forbids comparison of `void *' with function pointer Someone should upgrade that message; they were correct, but incomplete. ANSI C forbids comparison of function types with any other types. It's just a result of the requirement to compare only "compatible types." Use a cast to get the correct type in the right-hand operand: void foo (void (*fun) (void)) { if ( fun != (void (*) (void))NULL ) fun (); ... --Blair "And a cast of thousands."
steve@taumet.com (Stephen Clamage) (05/27/91)
bhoughto@pima.intel.com (Blair P. Houghton) writes: >In article <1991May21.125639.10052@umiami.ir.miami.edu> devebw9f@miavax.ir.miami.edu writes: >>#define NULL ((void *) 0) >>void foo (void (*fun) (void)) >>{ >> if (fun != NULL) /* Line with the warning. */ >> ... >>warning: ANSI C forbids comparison of `void *' with function pointer >Use a cast to get the correct type in the right-hand operand: > if ( fun != (void (*) (void))NULL ) This isn't really the best solution. NULL as defined in the standard ANSI headers is a pointer to an object (data), not pointer to a function. Where you need a null pointer to a function, use a literal 0, or a 0 cast to the appropriate type when calling a non-prototyped function. The usage if( fun != 0 ) ... is correct and IMHO more readable. By "correct", I mean that it is in strict conformance with ANSI C, and also conforms to early C (K&R1). When a cast is needed, one can argue about which of these two (void (*)(void) NULL) (void (*)(void) 0) is more readable (modulo whitespace). I don't think either is very readable, and I might use a typedef for void(*)(void) or a macro for the whole null pointer. BTW, the original example shows a programmer #define for NULL. Since NULL is a required macro in many ANSI standard headers, it is not a good idea to #define it yourself. You may run into a conflict with what is in the headers on some other system. -- Steve Clamage, TauMetric Corp, steve@taumet.com
gwyn@smoke.brl.mil (Doug Gwyn) (05/27/91)
In article <1991May21.125639.10052@umiami.ir.miami.edu> devebw9f@miavax.ir.miami.edu writes: >As the subject heading says, is there a NULL pointer to functions? Sure, just cast 0 to the appropriate function-pointer type. > if (fun != NULL) /* Line with the warning. */ if ( fun != (void(*)(void))0 )
bhoughto@pima.intel.com (Blair P. Houghton) (05/28/91)
In article <748@taumet.com> steve@taumet.com (Stephen Clamage) writes: >bhoughto@pima.intel.com (Blair P. Houghton) writes: >>Use a cast to get the correct type in the right-hand operand: > >> if ( fun != (void (*) (void))NULL ) > >This isn't really the best solution. NULL as defined in the standard >ANSI headers is a pointer to an object (data), not pointer to a function. Not so: "...NULL, which expands to an implementation-defined null pointer constant..." (ANSI X3.159-1989, sec. 4.1.5, p. 99, ll. 21-22) "Such a pointer, called a null pointer constant, is guaranteed to compare unequal to a pointer to any object OR FUNCTION." [emphasis mine --Blair] (Ibid, sec. 3.2.2.3, p. 38, ll. 3-4) >Where you need a null pointer to a function, use a literal 0, or a 0 >cast to the appropriate type when calling a non-prototyped function. [...] >BTW, the original example shows a programmer #define for NULL. Since >NULL is a required macro in many ANSI standard headers, it is not a good >idea to #define it yourself. You may run into a conflict with what is >in the headers on some other system. You have this right, but the specifications of `NULL' and `null pointer constant' pretty much make #define NULL 0 the only valid definition of `NULL,' although there may be others. Using `(void *) 0' as the value, however, will break the requirement in section 3.2.2.3, as shown above, since it won't compare legally at all with a function pointer, while the bare `0' will. >When a cast is needed, one can argue about which of these two > (void (*)(void) NULL) > (void (*)(void) 0) I argue "neither!" for punctuary reasons. :-) --Blair "One of us has done too many Margaritas this weekend, and I've only had six since Friday, so it ain't me. :-)"
bhoughto@pima.intel.com (Blair P. Houghton) (05/28/91)
In article <4428@inews.intel.com> bhoughto@pima.intel.com (Blair P. Houghton) writes: >"...NULL, which expands to an implementation-defined null >pointer constant..." >(ANSI X3.159-1989, sec. 4.1.5, p. 99, ll. 21-22) > >"Such a pointer, called a null pointer constant, is guaranteed to >compare unequal to a pointer to any object OR FUNCTION." [emphasis >mine --Blair] >(Ibid, sec. 3.2.2.3, p. 38, ll. 3-4) Oops. Total disconnect of the neural fabric. The word "constant" should be removed from the 3.2.2.3 quotation. The entire paragraph goes: "An integral constant expression with the value 0, or such an expression cast to type void *, is called a null pointer constant. If a null pointer constant is assigned to or compared for equality to a pointer, the constant is converted to a pointer of that type. Such a pointer, called a null pointer, is guaranteed to compare unequal to a pointer to any object or function." (Ibid., ll. 1-4) This doesn't abrogate the necessity that comparisons involve compatible types, however, nor that bare constants take the type of the object to which they are assigned or compared. --Blair "I get me some new specs, someday... @^O"
volpe@camelback.crd.ge.com (Christopher R Volpe) (05/29/91)
In article <748@taumet.com>, steve@taumet.com (Stephen Clamage) writes: |>bhoughto@pima.intel.com (Blair P. Houghton) writes: |> |>>In article <1991May21.125639.10052@umiami.ir.miami.edu> devebw9f@miavax.ir.miami.edu writes: |> |>>>#define NULL ((void *) 0) |>>>void foo (void (*fun) (void)) |>>>{ |>>> if (fun != NULL) /* Line with the warning. */ |>>> ... |>>>warning: ANSI C forbids comparison of `void *' with function pointer |> |>>Use a cast to get the correct type in the right-hand operand: |> |>> if ( fun != (void (*) (void))NULL ) |> |>This isn't really the best solution. NULL as defined in the standard |>ANSI headers is a pointer to an object (data), not pointer to a function. Is it really defined as a pointer to an object? I always see it defined as a "null pointer constant", (either "0" or "(void *) 0"), which is comparable to any pointer type, no? Section 3.2.2.3 says that a null-pointer- constant (and "(void *)0" is in fact a null pointer constant) can be assigned to or compared for equality to any pointer, including function pointers. ================== Chris Volpe G.E. Corporate R&D volpecr@crd.ge.com
hinton@gca.UUCP (Edward Hinton) (05/29/91)
In article <16269@smoke.brl.mil> gwyn@smoke.brl.mil (Doug Gwyn) writes: >In article <1991May21.125639.10052@umiami.ir.miami.edu> devebw9f@miavax.ir.miami.edu writes: >>As the subject heading says, is there a NULL pointer to functions? > >Sure, just cast 0 to the appropriate function-pointer type. > >> if (fun != NULL) /* Line with the warning. */ > > if ( fun != (void(*)(void))0 ) Now I'm going back a ways, but C doesn't necessarily define NULL as 0, although it's been quite a while since I've seen a system where it isn't. However, I recall a system where 0 WAS a valid address (small model on an 8086 based virtual memory system) and NULL was defined to be -1. Although this looks odd, I suggest: if ( fun != (void(*)(void))NULL ) Then again, it wouldn't necessarily surprise me if a definition of NULL existed for some C compiler on some machine to define NULL in a way that it wouldn't like this combination of casts. I haven't had to do this in ANSI C on any strange implementations yet.
scs@adam.mit.edu (Steve Summit) (05/29/91)
In article <632@gca.UUCP> hinton@gca.UUCP (Edward Hinton) writes: >Now I'm going back a ways, but C doesn't necessarily define >NULL as 0, although it's been quite a while since I've seen >a system where it isn't. However, I recall a system where 0 WAS a >valid address (small model on an 8086 based virtual memory system) >and NULL was defined to be -1. Regular readers of comp.lang.c recognize the fallacies in this statement, and I've just sent Ed a copy of the comp.lang.c frequently-asked questions list, so there should be no need to comment further on this aspect of the problem. Steve Summit scs@adam.mit.edu
gwyn@smoke.brl.mil (Doug Gwyn) (05/30/91)
In article <632@gca.UUCP> hinton@gca.UUCP (Edward Hinton) writes: >However, I recall a system where 0 WAS a >valid address (small model on an 8086 based virtual memory system) >and NULL was defined to be -1. While an implementation is allowed to make a construct like "((void*)-1)" act like a null pointer, it is also required (by the standard) to treat a null pointer constant written by the programmer as "0" (in certain contexts) or "((void*)0)" as a valid way of denoting a null pointer. Of course that does not mean that the implementation must internally use address value 0 to represent a null pointer. This, while ANY conforming implementation can define NULL in the standard headers as simply "0", this has nothing to do with address values. This topic is covered in the FAQ list, q.v..
mouse@thunder.mcrcim.mcgill.edu (der Mouse) (06/02/91)
In article <4429@inews.intel.com>, bhoughto@pima.intel.com (Blair P. Houghton) writes: [stuff about comparing pointer-to-function to NULL] > [ANSI X3.159-1989, sec. 3.2.2.3, says] > "An integral constant expression with the value 0, or such an > expression cast to type void *, is called a null pointer > constant. If a null pointer constant is assigned to or > compared for equality to a pointer, the constant is converted > to a pointer of that type. Such a pointer, called a null > pointer, is guaranteed to compare unequal to a pointer to any > object or function." > This doesn't abrogate the necessity that comparisons involve > compatible types, however, nor that bare constants take the type of > the object to which they are assigned or compared. But I believe it *does* require that comparing a function pointer to (void *)0 convert the null pointer to the appropriate function pointer type, which the compiler in the original posting was not doing. (Or at least was not being silent about.) der Mouse old: mcgill-vision!mouse new: mouse@larry.mcrcim.mcgill.edu