SIZEOF

Guy Harris guy at rlgvax.UUCP
Mon Jan 28 08:10:44 AEST 1985


> Of course, C SHOULD be defined to allow sizeof(int) != sizeof(int *).
> However, due to one point in the Reference Manual, and K&R (and, I assume,
> the standard, although I haven't checked), they are actually required to
> be equal.  The problem is that "0" is defined to be the Null pointer
> constant.

This has been said about 1.0E6 times before, but "0" is NOT defined to be
the null pointer constant.  K&R says:

	...it is guaranteed that *ASSIGNMENT* (emphasis mine) of the
	constant 0 to a pointer will produce a null pointer distinguishable
	from a pointer to any object.

Passing something as an argument doesn't behave like an assignment, precisely
because the compiler can't perform the proper type coercions.  You have
to do so yourself; if you want to pass an "int" to a routine that expects
a "double", you have to say "(double) foo", whereas if you wanted to assign
that int to a double you could omit the case and the compiler would perform
the coercion for you.  The same holds for passing 0 to a routine expecting
a pointer and assigning 0 to a pointer.  You have to cast it.

"lint" complains, and rightly so, if you pass an object of one type to
a routine which expects an object of another type.  It's *VERY EASY* to
catch this kind of problem - just run "lint" every once in a while.

We support 16-bit "int"s and 32-bit pointers on our machines; if this
causes somebody's code to have problems because it says things like

	execl("/usr/local/foo", "foo", "bar", 0);

instead of

	execl("/usr/local/foo", "foo", "bar", (char *)0);

it's because the code is incorrect.  Period.

> Of course, many compilers do not conform to this requirement.

It's not a requirement, so compilers don't have to conform.

> The problem can be avoided by, for example, always using (say) NULL as
> the Null address constant, where NULL is #defined as something like
> ((char *) 0).

OK.  Everybody take a deep breath and repeat after me:

THER IS NO ONE NULL ADDRESS CONSTANT IN C!

There is no such thing as a generic "pointer" in C.  There are pointers to
characters, pointers to "int"s, pointers to "struct proc", pointers to...
As such, there is no such thing as a generic null pointer.  There are null
pointers to no character, null pointers to no "int", etc..  As such, the
problem should not be avoided by the above trick.  "lint" will complain,
and the code will choke on implementations where "char *" and "int *" have
different representations (a word-addressed machine where a byte pointer
would take more bits than fit in a word pointer REQUIRES such an
implementation).

> The real solution, of course, would be to introduce a new keyword, say "null",
> which represents the Null address constant, with an implementation-
> defined value.  However, I doubt that that will ever come about.

Let's hope not.  It is an incorrect solution for the very reason mentioned
above.  The clses thing to a correct solution is the introduction of
declarations of functions that declare the argument types; thus, the
compiler could perform the necessary coercions just as it can do so in
expressions.

> Anyone who has made much effort at porting C code has no doubt encountered
> this problem, but I don't think it is as well known as it should be.

Anyone who has made much effort at porting C code has encountered lots of
problems, all too many of which are due to people misusing the language.
Many of those can be avoided by using "lint".  Go forth and do so.

Let's hope this kills this discussion off until the next time it shows up
(which will probably be in another couple of months - it keeps returning
like a bad penny).

	Guy Harris
	{seismo,ihnp4,allegra}!rlgvax!guy



More information about the Comp.lang.c mailing list