einari@rhi.hi.is (Einar Indridason) (11/08/90)
I just 'troff'-ed Henry Spencer's 10 commandments and read it. It is great and it is now hanging in my wall at home. However one question entered my mind: (a question that perhaps should be in the FAQ list, and perhaps is there?) The question is about NULL pointers. Suppose I have the following code: ------------------------------------------------------ #include <whatever_needs_to_be_included.h> int do_something(int *par1, double *par2, char *par3) { /* do something with those pointers/parameters */ /* return some value to tell how well we did */ } main() { ..... x = do_something(NULL, NULL, NULL); /* is ^^^^ ^^^^ ^^^^ this right or should I write: */ x = do_something( (int *)NULL, (double *)NULL, (char *)NULL ); /* which form should I use? (that is, should I cast the NULL value */ /* to int pointer, double pointer, char pointer?) */ } ----------------------------------------- Thanks for your time. -- Internet: einari@rhi.hi.is | "Just give me my command line and drag UUCP: ..!mcsun!isgate!rhi!einari | the GUIs in the waste basket!!!!" General Surgeons warning: Masking the 8th bit can seriously damage your brain!!
hp@vmars.tuwien.ac.at (Peter Holzer) (11/08/90)
einari@rhi.hi.is (Einar Indridason) writes: >#include <whatever_needs_to_be_included.h> >int do_something(int *par1, double *par2, char *par3) >{ > /* do something with those pointers/parameters */ > /* return some value to tell how well we did */ >} >main() >{ > ..... > x = do_something(NULL, NULL, NULL); > /* is ^^^^ ^^^^ ^^^^ this right or should I write: */ > x = do_something( (int *)NULL, (double *)NULL, (char *)NULL ); > /* which form should I use? (that is, should I cast the NULL value */ > /* to int pointer, double pointer, char pointer?) */ >} >----------------------------------------- If you are using ANSI C, then the above form is allright, because the compiler knows from the prototype above the types of the pointers and inserts the casts by itself. If you (or someone else) want to port your program to an old compiler (and many of them are still in use) and change the declaration of do_something to: int do_something (par1, par2, par3) int * par1; double * par2; char * par3; { /* ... */ } you will need the casts because the compiler does not check (much less convert) any arguments. -- | _ | Peter J. Holzer | Think of it | | |_|_) | Technical University Vienna | as evolution | | | | | Dept. for Real-Time Systems | in action! | | __/ | hp@vmars.tuwien.ac.at | Tony Rand |
jc@atcmp.nl (Jan Christiaan van Winkel) (11/08/90)
From article <2390@krafla.rhi.hi.is>, by einari@rhi.hi.is (Einar Indridason): # int do_something(int *par1, double *par2, char *par3) # { # /* do something with those pointers/parameters */ # /* return some value to tell how well we did */ # } # # # main() # { # ..... # # x = do_something(NULL, NULL, NULL); # /* is ^^^^ ^^^^ ^^^^ this right or should I write: */ # # x = do_something( (int *)NULL, (double *)NULL, (char *)NULL ); # } since you used prototypes, you can just as well use x = do_something(0, 0, 0); because the compiler knows the 0's are used in pointer context; it will automagically cast the value to the right type. Read the FAQ for more info on the NULL pointer, there's actually quite a lot to be told about it. JC -- ___ __ ____________________________________________________________________ |/ \ Jan Christiaan van Winkel Tel: +31 80 566880 jc@atcmp.nl | AT Computing P.O. Box 1428 6501 BK Nijmegen The Netherlands __/ \__/ ____________________________________________________________________
chris@mimsy.umd.edu (Chris Torek) (11/09/90)
In article <2390@krafla.rhi.hi.is> einari@rhi.hi.is (Einar Indridason) writes: >However one question entered my mind: (a question that perhaps should >be in the FAQ list, and perhaps is there?) It is. >int do_something(int *par1, double *par2, char *par3) ... > x = do_something(NULL, NULL, NULL); > /* is ^^^^ ^^^^ ^^^^ this right or should I write: */ You have provided a prototype declaration (via a preceding prototype definition) in which all three parameters are covered by prototypes. They are therefore in assignment contexts and as a result, an integer constant zero or same-cast-to-void (NULL expands to one of these two) suffices, because the pointer context is supplied by the assignments. > x = do_something( (int *)NULL, (double *)NULL, (char *)NULL ); > /* which form should I use? (that is, should I cast the NULL value */ > /* to int pointer, double pointer, char pointer?) */ Some people prefer the latter form even when prototypes are used, as it helps remind the reader what is going on. Still others prefer something like: /* special distinguished second parameter to DoSomething */ #define NOMATRIX ((double *)NULL) ... x = do_something(NOFOO, NOMATRIX, NOBAR); -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 405 2750) Domain: chris@cs.umd.edu Path: uunet!mimsy!chris
gwyn@smoke.brl.mil (Doug Gwyn) (11/09/90)
In article <2390@krafla.rhi.hi.is> einari@rhi.hi.is (Einar Indridason) writes: > x = do_something(NULL, NULL, NULL); > /* is ^^^^ ^^^^ ^^^^ this right or should I write: */ > x = do_something( (int *)NULL, (double *)NULL, (char *)NULL ); Use the latter. The former might or might not work, depending on system details.
gwyn@smoke.brl.mil (Doug Gwyn) (11/09/90)
In article <681@atcmpe.atcmp.nl> jc@atcmp.nl (Jan Christiaan van Winkel) writes: >since you used prototypes, you can just as well use > x = do_something(0, 0, 0); Only if there is a prototype declaration of do_something() in scope; it is better to not rely on such automatic pointer coercion (available only under ANSI C) and instead just supply the right types.