read(fd,&y,sizeof y)

Guy Harris guy at rlgvax.UUCP
Mon Mar 19 03:58:32 AEST 1984


> I don't think this is non-portable.  For a machine which has pointers of more
> than one width, the compiler can be expected to widen the shorter ones to
> the width of the largest as it is pushed onto the argument list, just as
> chars are promoted to ints when pushed.  The called function will know it's
> stored that way and shorten it if it needs to before it's used.

Anyone who expects a C compiler to do this is going to be sorely disappointed.
There is NOTHING in K&R which says that this must be done, and there is no
reason for a compiler to do so.  It is explicitly stated in K&R that integer
and floating point values are coerced to "int" and "double", respectively, so
one would expect this to happen.

> So it doesn't matter what the type of "y" is in the read call is or what
> the actual width of &y is.  It seems simple to me that there should be only
> one width of a pointer on the argument stack [Not necessarily the width of
> an int, either].

WHY?  Why should there be only one width of a pointer on the argument stack?
Just to make life easier for lazy programmers who refuse to write type-correct
code no matter how often they've been told to?  The analogy between different
widths of "int" and different width of pointer breaks down because there is
a semantic difference between "char", "short", "int", and "long" in the C
language that pertains directly to the width of the object; the semantic
difference between "char *" and "int *" has nothing to do with the *width*
of those pointers - any difference or lack of same between their widths is
purely a consequence of the C implementation and of the architecture of the
underlying machine.

> p.s. this also speaks to the NULL vs. 0 vs. ((char *) 0) issue.

No, it doesn't.  Even if a C compiler took the ill-advised step of "widening"
pointers when passed as arguments, this would have no effect on a program
which illegally passed an "int" of 0 to a routine expecting a pointer.

We've repeatedly heard ideas for changes to the C language or the C compiler
to "solve" the "problem" caused by the facts that 1) C has several different
pointer types which may not have identical implementations and 2) that null
pointers in C are represented by coercing the "int" value 0 to a pointer, and
that C has no way of telling the compiler what kinds of arguments a function
takes, so the 0 value must be coerced explicitly with a cast when passed
to a function.  THIS ISN'T A "PROBLEM", FOLKS, AND IT DOESN'T REQUIRE A
"SOLUTION".  The way to "solve" the "problem" is to write type-correct code
and explicitly cast all NULLs or 0s passed as values to routines expecting
pointers.  This requires NO changes to C, or to any correct C compilers; it
merely requires changes to incorrect C code and to the incorrect models of
the C language held by certain programmers.  And if you have trouble finding
all the places you forgot to cast pointers, well, there's a very nice tool -
at least on UNIX - to fix this.  It's called "lint".  USE IT.

This non-problem requires no further debate; there is only one correct way to
deal with it.

	Tired of explaining pointers, and tired of pointing people back to
		K&R,
	Guy Harris
	{seismo,ihnp4,allegra}!rlgvax!guy



More information about the Comp.unix.wizards mailing list