Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!mnetor!seismo!rutgers!dayton!rosevax!sds!dave From: dave@sds.UUCP (dave schmidt x194) Newsgroups: comp.lang.c Subject: pointer debate raging on... (LONG) Message-ID: <149@sds.UUCP> Date: Sat, 25-Apr-87 14:57:45 EDT Article-I.D.: sds.149 Posted: Sat Apr 25 14:57:45 1987 Date-Received: Sun, 26-Apr-87 23:31:49 EDT Organization: SciCom Data Services, Minnetonka, MN Lines: 122 [This disucssion has been going on in news.software.b; while I was under the belief that it had been cross-posted to comp.lang.c, I don't believe that it has. If this duplicates too much material, my apologies...] Summary: Someone asked if anyone had ported the news software to the IBM AT; I replied that I had done so, but had a few problems with the programs assuming that sizeof(ptr) == sizeof(int). I also commented that constructs such as "if (!charptr)" were present. Having had bad experience with such constructs, I changed them to "if (charptr == (char *)NULL)" before compilation. guy%gorodish@Sun.COM commented that if such code didn't work, the compiler was in error as the two statements are identical in meaning. Based on what I had seen more than one C compiler (or "alledged C compiler") do, I asked why the statements were identical rather than "if ((int)charptr == 0)". gwyn@brl.arpa, among others, correctly pointed out that the language definition required the statements to be interpreted as Guy had said. We now join the conversation in progress... gwyn@brl.arpa (Doug Gwyn (VLD/VMB) writes; >No cast is needed for the 0; 0 has special pointer properties in addition >to its use as an integer constant.... >Guy's explanation is EXACTLY RIGHT independent of machine >architecture or implementation, including bit pattern used to represent a >null pointer (always written as 0 at the C source level regardless of the >implementation). All this seems to say is when faced with a statement such as if ( charptr == 0 ) the 0 is cast to (char *), just as 0 is cast to (double)0 in if ( doublevar == 0 ) In a certain sense, therefore, I still maintain that if ( charptr == (char *)0 ) is more correct and better style. Again, this bias of mine comes with working with brain-damaged compilers which do not correctly compare 32-bit pointers to 16-bit ints. guy%gorodish@Sun.COM (Guy Harris) writes: >So a C compiler *must* properly handle "if (charptr == 0)". It MUST >not do an integer comparison if that would give a different result >from a pointer comparison. In effect, it must convert the "0" to a >character pointer of the appropriate type. What I said. I incorrectly stated that in an implementation where NULL was #defined as 0xffffffff, that "if (!charptr)" would not work; Guy, Doug, and blarson@castor.usc.edu.UUCP correctly pointed out that this was wrong... blarson@castor.usc.edu.UUCP writes: >>(from me) >>Coding the above as "if (charptr == (char *)NULL)" saves you from the >>"queer machine"; it is also more correct in that it explicitly states what >>you desire and is more portable. >Writing code to avoid everything that is broken in some compiler is impossible. >Why bother trying? Well, you obviously can't save yourself from every potential muck-up a compiler can inflict on you. On the other hand, if a construct has caused you problems in more than one compiler, and an equivalent construct never has, which would you write? And wouldn't you be a little frustrated if you had to modify (note I did not say fix) virtually every piece of p.d. software that you tried to bring up because of this construct? (Patch was a notable exception to this; not one line of code needed to be modified. The author(s) should be whole-heartedly commended.) john@viper.UUCP (John Stanley) writes: >In article <5787@brl-smoke.ARPA> gwyn@brl.arpa (Doug Gwyn (VLD/VMB) ) writes: >> >>He, I, and others have explained more than once before in the C newsgroup >>that the only fully correct definition of the macro NULL, as C now stands, >>is as 0. (Under the proposed ANSI standard you could probably get away >>with defining it as (void *)0.) >> >Actualy, you -must- use (void *)0 -OR- 0 and be consistant one way or >the other. It's not an option... If I had to choose, I'd say use > #define NULL ((void*)0) >because it's used as a pointer in 98% of the code I've seen and for >the following reason... >This isn't important on machines where sizeof(pointer) == sizeof(int), >but if you're using (as a simple example) a machine where pointers are >32 bit and ints are 16 bits then code containing the following function >may have problems if you change how NULL is defined: [example deleted] >If you use NULL as a pointer, it -must- always actualy be a pointer or >your code will break any time you try to pass it as a constant to a >function. Applaud, applaud, applaud. John has correctly pointed out that sizeof(pointer) == sizeof(int) is not the universal constant that many people believe it to be. It is for this exact reason that NULL should ***NOT*** be defined as 0. A minor problem still exists even with defining NULL as (void *)0; NULL cannot be passed to a routine as function pointer without a cast since sizeof(void (*)()) may not be the same as sizeof(void *). That, however, is something that shouldn't cause too much trouble. Dave Schmidt