www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - null in D

reply bearophile <bearophileHUGS lycos.com> writes:
This is the C FAQ:
ftp://ftp.eskimo.com/u/s/scs/C-faq/faq.gz
at the point 5.2: it says:

an argument being passed to a function is not necessarily recognizable as a
pointer context, and the compiler may not be able to tell that an unadorned 0
"means" a null pointer.  To generate a null pointer in a function call context,
an explicit cast may be required<
(Later the FAQ also explains why). So essentially in C this is the right thing to call foo() that takes a pointer to int (using 0 instead of NULL is the same): foo((int *)NULL); So in D is this better, like in C: foo((int *)null); Or is this always enough in D? foo(null); Bye, bearophile
Aug 19 2008
parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
"bearophile" wrote
 This is the C FAQ:
 ftp://ftp.eskimo.com/u/s/scs/C-faq/faq.gz
 at the point 5.2: it says:

an argument being passed to a function is not necessarily recognizable as 
a pointer context, and the compiler may not be able to tell that an 
unadorned 0 "means" a null pointer.  To generate a null pointer in a 
function call context, an explicit cast may be required<
(Later the FAQ also explains why). So essentially in C this is the right thing to call foo() that takes a pointer to int (using 0 instead of NULL is the same): foo((int *)NULL); So in D is this better, like in C: foo((int *)null); Or is this always enough in D? foo(null);
I would expect this probably is a side effect of 1) that NULL is not part of the language, and 2) some C standard libraries define NULL as 0. Some define NULL as (void*)0, which probably don't have this problem. I expect in D that since null is a first-class keyword, and not some alias or definition, its usage is understood correctly by the compiler to always be a pointer or null reference. That being said, overloaded functions which have 2 versions which take different reference types must be selected by using a cast. For example: foo(int *i) {...} foo(char *c) {...} foo(null); // which one to call? -Steve
Aug 19 2008
parent reply bearophile <bearophileHUGS lycos.com> writes:
Steven Schveighoffer:
 I would expect this probably is a side effect of 1) that NULL is not part of 
 the language, and 2) some C standard libraries define NULL as 0.  Some 
 define NULL as (void*)0, which probably don't have this problem.
Well, what you say here is generally not precise/almost wrong regarding C; that FAQ explains how things are. And NULL defined as (void*)0 can't solve that problem, it seems. I did suppose to know enough C before reading that FAQ ;-)
 I expect in D that since null is a first-class keyword, and not some alias 
 or definition, its usage is understood correctly by the compiler to always 
 be a pointer or null reference.
I expect it too, but I'd like to be sure :-)
 That being said, overloaded functions which have 2 versions which take 
 different reference types must be selected by using a cast.
I agree. Bye and thank you, bearophile
Aug 19 2008
parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
"bearophile" wrote
 Steven Schveighoffer:
 I would expect this probably is a side effect of 1) that NULL is not part 
 of
 the language, and 2) some C standard libraries define NULL as 0.  Some
 define NULL as (void*)0, which probably don't have this problem.
Well, what you say here is generally not precise/almost wrong regarding C; that FAQ explains how things are. And NULL defined as (void*)0 can't solve that problem, it seems. I did suppose to know enough C before reading that FAQ ;-)
OK, I just read that section of the FAQ and also on the NULL definition. I'll update my statement. It is not required to use a cast to qualify an unadorned NULL as long as the definition of NULL is (void *)0. This qualification tells the compiler that the 0 is not an integer (whose size is implementation dependent, and might not be of pointer-size), but is in fact a full pointer-sized zero. If NULL is defined as simply 0, then a qualification is necessary in some circumstances. It appears that the only place this is an issue is for unprototyped functions and for variadic functions. The gist of it is, you are declaring a type for the 0, not just assuming the compiler is assigning the correct type.
 I expect in D that since null is a first-class keyword, and not some 
 alias
 or definition, its usage is understood correctly by the compiler to 
 always
 be a pointer or null reference.
I expect it too, but I'd like to be sure :-)
You can be sure :) null is always typed as a pointer, which means it should always be passed as a pointer-sized value. The two cases I can think of where a cast is necessary are for when you wish to pass a typed null pointer to a D variadic function (to allow D to declare the correct type), or when you have overloads of pointer-typed arguments and you want to pass null. However, the problems that are associated with C, in that it doesn't pass the right amount of data to a function, cannot happen with D. -Steve
Aug 19 2008