guy@rlgvax.UUCP (Guy Harris) (03/18/84)
> 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
jbf@ccieng5.UUCP (Jens Bernhard Fiederer) (03/28/84)
Speak for yourself. The need to cast every null pointer argument to the specific pointer required IS A PROBLEM WITH THE C LANGUAGE. It is a bloody pain, not to mention a waste of time. I do it, but I would rather not. Three cheers for the set of languages that support the "lazy" programmer! Three cheers for the empty set! Azhrarn -- Reachable as ....allegra![rayssd,rlgvax]!ccieng5!jbf Or just address to 'native of the night' and trust in the forces of evil.
aaw@pyuxss.UUCP (Aaron Werman) (03/28/84)
<set -nt> why not put together a suite of macros like: #define Read(fd, charP, charCount) \ ( (int) read((file *)fd, (char *)charP, (int) charCount) ) #define Ldtseek(lp) ( (int) ldseek( (LDFILE *) ld) ) or alternatively you could recode all routines in your system to accept only full words (passed as "char *" to be known heretoafter as the "universal type"). Each system routine would thus merely have to cast the type in statements, like typedef char * WORD; WORD strlen(s) WORD s;{ WORD p = s; while (*p++); return (WORD) (p - s - 1);} -but BCPL did it first, and saved time on casts. {harpo,houxm,ihnp4}!pyuxss!aaw :-) Aaron Werman
gwyn@brl-vgr.ARPA (Doug Gwyn ) (03/31/84)
Personally I wish C had even stronger data typing, not weaker. (I like the compiler to catch my occasional minor coding slips and strong typing [within reason!!] helps it do this.)