Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!mnetor!seismo!mimsy!chris From: chris@mimsy.UUCP (Chris Torek) Newsgroups: comp.lang.c Subject: Re: To comment 48: Xenix Message-ID: <6464@mimsy.UUCP> Date: Sun, 26-Apr-87 01:08:26 EDT Article-I.D.: mimsy.6464 Posted: Sun Apr 26 01:08:26 1987 Date-Received: Sun, 26-Apr-87 22:33:11 EDT References: <77200001@uiucdcsp> Organization: U of Maryland, Dept. of Computer Science, Coll. Pk., MD 20742 Lines: 107 In article <77200001@uiucdcsp> lopez@uiucdcsp.cs.uiuc.edu writes: >The problem of having pointers that are not the same length as integers >cost me a day and alot of steam. But I think that declaring: >#define NULL (char *)0 >is expensive but will always do the trick for all models (small,large,huge) This is wrong: It will not always work. In fact, it will not work on at least two existing machines, both of which have C compilers. (DG MV series and PR1ME series have 48 bit char pointers, but 32 bit word (integer, structure, &c) pointers. Passing one (char *)0 and one int to a function that expects one (int *)0 followed by one int will give you a much-deserved surprise.) >On UNIX System V AT I had done the typical tricks in C of: > if (!charptr) >Even though I new [sic] it was crypt [sic], but efficient. There is really nothing illegal about this, although it is considered bad style by many. It is also no more efficient than if (charptr == NULL) or if (charptr == 0) ---both of which MUST mean the same thing, or the compiler or the environment is broken. >... after alot of frustration I figured out that NULL was defined >as 0L. Which makes sense since we need a 32 bit zero value, which >is not an integer. double pow(); extern double no; printf("%g\n", pow(no, 1000.0)); You do not need a 32 bit zero value. You need a null pointer to char. A null pointer to char is not a 32 bit zero value. It is not a 16 bit zero value. It is not an 18 bit zero value. It is not a 36 bit zero value. It is not a 48 bit zero value. It is all of these, and none. It is a null pointer to char. A null pointer to char is a null pointer to char. A null pointer to char is a null pointer to char. (What I tell you three times is true.) >But As for people saying that if (charptr == 0) should work, >"for any good C programmer's" I think thats hogwash. It has nothing to do with programmers. Any correct C *compiler* will compare `charptr' with an appropriately typed null pointer, not with a 16 bit integer zero, nor with a 32 bit integer zero, nor with an 18 bit integer zero, nor a 36 bit zero nor a 48 bit zero. All of these happen to correspond to certain machines' ideas of null pointers, but a null pointer is a null pointer, not any of these odd objects. In an assignment or comparison context when the other operand is a pointer, the integer constant value zero is converted to a null pointer of the appropriate type. In other contexts, no conversion is performed, and the programmer must provide an appropriate cast. It is legal (though unnecessary) to write if (charptr == (char *) 0) or if (charptr == (char *) NULL) It is *not* legal (with an exception mentioned below) to write n = scandir(dir, &names, NULL, NULL) because scandir wants two pointers to function returning integer. It is legal and necessary to write n = scandir(dir, &names, (int (*)()) NULL, (int (*)()) NULL) or something equivalent. If you run lint, it will properly complain about incorrect function calls. Exception: If you use a dpANS-conformant compiler with function prototypes, the function prototype can supply assignment context for function parameters, making the first of the two `scandir' calls legal. Of course, there must be a scandir prototype in scope at the time of the call. >On every system I have ever used if (!charptr) worked, (because it must) > if (charptr == NULL) > is easier to read by everyone, and less likely to be a source of > unexpected bugs. (I agree.) -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7690) UUCP: seismo!mimsy!chris ARPA/CSNet: chris@mimsy.umd.edu