Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10.1 6/24/83; site umcp-cs.UUCP Path: utzoo!watmath!clyde!burl!ulysses!allegra!mit-eddie!godot!harvard!seismo!umcp-cs!chris From: chris@umcp-cs.UUCP (Chris Torek) Newsgroups: net.lang.c Subject: Re: SIZEOF Message-ID: <2716@umcp-cs.UUCP> Date: Sat, 26-Jan-85 23:18:43 EST Article-I.D.: umcp-cs.2716 Posted: Sat Jan 26 23:18:43 1985 Date-Received: Tue, 29-Jan-85 06:41:02 EST References: <347@ecr.UUCP> Organization: U of Maryland, Computer Science Dept., College Park, MD Lines: 66 > [...] C SHOULD be defined to allow sizeof(int) != sizeof(int *). > However, due to one point in the Reference Manual, [...] they are > actually required to be equal. The problem is that "0" is defined to > be the Null pointer constant. When "0" is passed as a parameter to a > function, the compiler cannot tell whether an int or an int * is > intended. The effect of this is that sizeof(int) must equal > sizeof(int *), and even more, the value of the Null address constant > must be bit-for-bit identical to the value of ((int) 0). NO! NO! and NO! [please turn your volume control way up] PASSING AN UNCASTED ZERO TO A ROUTINE THAT EXPECTS A POINTER IS NOT PORTABLE, AND IS JUST PLAIN WRONG. GET THAT STRAIGHT *NOW*! [you can turn your volume control back down] The following code is NOT portable and probably fails on half the existing implementations of C: #define NULL 0 /* this from */ f() { g(NULL); } g(p) int *p; { if (p == NULL) do_A(); else do_B(); } The value ``f'' passes to ``g'' is the integer zero. What that represents inside g is completely undefined. It is not the nil pointer, unless your compiler just happens to work that way (not uncommon but not universal). It may not even be the same size (in bits or bytes or decidigits or whatever your hardware uses). One tiny little simple change fixes it: f() { g((int *)NULL); } It is now portable, and all that good stuff. You can write the first and hope real hard, or you can write the second and know. The point is that the zero value and the nil pointer are two completely different things, and the compiler happens to be obliged to convert the former to the latter in expressions where this is forced (e.g., casts or comparison with another pointer). It is NOT forced in function calls (though under the ANSI standard it would be in some cases). (I claim that it IS forced in expressions such as if (p) where p is a pointer; this is "if (p != 0)" where type-matching p and 0 forces the conversion.) (Now I WILL agree that if you have the option of making the nil pointer and the zero bit pattern the same, then you will have less trouble with existing programs if you do....) -- (This line accidently left nonblank.) In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7690) UUCP: {seismo,allegra,brl-bmd}!umcp-cs!chris CSNet: chris@umcp-cs ARPA: chris@maryland