[comp.lang.c] Casting NULL?

Peter@adm.UUCP (01/23/87)

Its me again, although not about my infamous reviewer.

I have a question about pointers: I just recently read
a C text where whenever NULL was passed as a parameter
it was casted to the proper type. For example, if he had

void test(pc,pi)
char *pc;
int *pi;
{
  ...
}

he would call it as

test( (char *)NULL, (char *)NULL );

if the parameters were to be passed as NULL. He claimed that
this is required because pointers to different types of objects
may not be the same size. I can appreciate this but how common
is it really? Are there any byte architectures out there where
a pointer to one type of object is a different size than a pointer
to another type of object? I know that under MS-DOS, some compilers
support so-called "far" declarations, but that's not really the
same. Would anyone care to respond?

Try sending to me directly to Peter@Acadia.BITNET. If that doesn't
work, just post it over info-c.

Peter Steele

dvadura@watdaisy.UUCP (01/23/87)

In article <3179@brl-adm.ARPA> Peter Steele - Acadia writes:
>I have a question about pointers: I just recently read
>a C text where whenever NULL was passed as a parameter
>it was casted to the proper type.
>
>He claimed that
>this is required because pointers to different types of objects
>may not be the same size.

I don't know how common it is, but a simple solution is to define:

#define NIL(a) (a *)NULL;

when you need to pass a null pointer to an int or a char then say

	NIL( int ) or NIL( char )

this works for structs and other objects as well.

     	typedef foo { .... } BAR;

then NIL( BAR ) is a NULL pointer of type BAR.

gwyn@brl-smoke.UUCP (01/24/87)

In article <3179@brl-adm.ARPA> Peter Steele - Acadia writes:
>test( (char *)NULL, (char *)NULL );
>this is required because pointers to different types of objects
>may not be the same size. I can appreciate this but how common
>is it really?

It's quite common, and furthermore NULL is usually 0 (an integer),
which is often of a different size than any pointer.  (Guy Harris,
among others, explains this once or twice a year in this newsgroup.)

Using an X3J11-compliant C implementation, if a function prototype
is in scope when the invocation occurs, the parameters will be
automatically converted to the type defined in the prototype.
(Some of us don't like this feature, by the way, feeling that it
encourages sloppy programming practices.)

The really best way to think while coding C is to treat all data
as strictly-typed, maintain absolute consistency in use of types,
and in the (rare) instances when a type conversion is required,
show it explicitly by using an appropriate cast.  When I adopted
this mental discipline, the reliability of my C code improved
significantly (not to mention its portability).  I even take it a
step farther and maintain a distinction between Boolean and
integer data types (not enforced by the language), using only
Boolean expressions in conditionals, for example.  This is perhaps
the simplest example of the very important general principle of
"data abstraction", which should be explained in good Computer
Science textbooks.

guy%gorodish@Sun.COM (Guy Harris) (01/24/87)

>I have a question about pointers: I just recently read
>a C text where whenever NULL was passed as a parameter
>it was casted to the proper type.

All praise to the author of the text for that!

>He claimed that this is required because pointers to different types of
>objects may not be the same size.

That isn't the half of it.  NULL is *!*!NOT*!*!* a pointer, in most
implementations of C, it's just 0.  (There are good reasons for
this.)  There are plenty of implementations where 0 and "(char *)0"
are not the same size.

Furthermore, there is no guarantee whatsoever that an integral
constant 0 and and a null pointer of some type have the same bit
pattern.