Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!utgpu!water!watmath!clyde!rutgers!sri-spam!ames!oliveb!sun!gorodish!guy From: guy@gorodish.UUCP Newsgroups: comp.lang.c Subject: Re: Religion vs. Reality (no smiling allowed) Message-ID: <17576@sun.uucp> Date: Tue, 28-Apr-87 22:58:28 EDT Article-I.D.: sun.17576 Posted: Tue Apr 28 22:58:28 1987 Date-Received: Fri, 1-May-87 00:45:58 EDT References: <31@thirdi.UUCP> <17498@sun.uucp> <33@thirdi.UUCP> Sender: news@sun.uucp Lines: 88 > (See my response to Chris Torek regarding my use of the word "require" > with regard to #define NULL ((char *)0). ) Also note your own article, in which you indicate that you chose a technique for expressing the required casts of null pointers that obviates the need for embedding a cast in the definition of NULL. In fact, you also indicate the reason why you chose this technique was, in fact, that embedding a cast in the definition of NULL is NOT sufficient to solve the problem. In other words, the defensive programming encouraged by an earlier poster requires that you write your code in such a fashion as to make the definition of NULL as anything other than 0 unnecessary. As such, why do people continue to argue that there is some merit to defining NULL as something other than 0? > The existence of an objective standard and the acknowledgement of > that standard by way of validated implementations are two entirely > different things. The real world is composed mainly of implementations > that are "great" if they are a near-miss of some standard. Many systems > do not get as close as a near-miss. However, this in no way justifies the acceptance of blatant errors (such as compiling "if (!charptr)" into something other than a comparison of "charptr" with a null poiner), or indicates that the "real" definition of C requires that such comparisons be written as "if (charptr == (char *)NULL)". We're not talking nits here; we're talking C Programming 101. If some implementor can't get that right, why should I trust them to have gotten anything else right? There is a tradeoff involved here. If an implementation is fundamentally flawed, the cost of trying to find all cases where perfectly legitimate C code could exceed the benefits of making your code work in that implementation. For those of you who came in late, I present the following from the article that kicked this discussion off in the first place: > 4: stupid problems from [censored] programmers who think that > sizeof(int) == sizeof(char *) is a universal constant. similiar > problems from similar programmers who assign pointers of different > types w/o casts. (e.g. char * = char ** w/ no cast). also present > are things like: > charptr = malloc(1024); > if ( !charptr ) ... /* this should be (charptr != (char *)NULL) */ OK. Now it is true that setbuf(stream, NULL); is a case of code written by a programmer who was careless about casting pointers. HOWEVER, what I objected to was lumping the "if (!charptr)" into this category. It is WRONG to censure a programmer for using this construct because it doesn't happen to work on some broken compiler. It is not the responsibility of the developers of netnews (or any other program) to worry about the myriad ways in which somebody can get a C implementation wrong. If you happen to be stuck with a compiler that exhibits this behavior, that's your problem; it is not the responsibility of the authors of netnews to write their code so as to avoid that compiler's problem. Let us take an example of a C implementation with a fairly fundamental flaw. (This implementation really existed, and at one point I had to use it.) This particular implementation provided separate I&D space, and represented a null pointer by an all-zero bit pattern. However, it did not provide a shim at location 0 of the data segment, as is required in order to ensure that a null pointer not refer to any object. The fact that this implementation exists does not mean that C "really" doesn't guarantee that null pointers do not point to an object; it means that the implementation is flawed, and that the user is required to fix the implementation. This particular problem was fairly straightforwardly fixed by linking in an extra module that stuck the shim in. To put it bluntly, programmers have only a finite amount of time to worry about code that doesn't work on a given implementation. I, for one, will devote a lot more effort to fixing incorrect code that doesn't work on a correct implementation that I will devote to "fixing" correct code that doesn't work on an incorrect implementation, and will devote a lot more effort to fixing incorrect implementations on which correct code doesn't work than I will devote to "fixing" correct implementations on which incorrect code doesn't work.