Menu

Rant: NULL VS. 0

2006-01-03
2012-09-26
  • Nobody/Anonymous

    A note to new programmers:

    Stop using NULL when you mean 0!
    Stop using 0 when you mean NULL!
    Don't use NULL as an integer replacement!

    I just DL'ed some source and received nearly four hundred "passing NULL to non-pointer type argument" errors.

    Here is the deal. NULL is defined as (void *)0 by the standard. In C++ it is no way the same as 0, but in both C and C++ 0 can be used in place of NULL. So if you come accross an optional argument to an API that should be set to 0 then use 0! Do not use NULL. If you come accross an API that requires an argument be passed NULL use 0. Only a fool would redefine NULL so it is completely safe and type safe to use 0 when an integer type or a pointer type is required, but using NULL is only type safe when using it as a pointer to a type. This means that people like me, and most professional programmers, who like to see code compile cleanly have to fix the errors/warnings. This is time consuming. Don't use NULL!

     
    • Paul van Zelst

      Paul van Zelst - 2006-01-03

      Amen. I personally never use NULL. 0 works just fine.

      Paul

       
    • Br5an

      Br5an - 2006-01-03

      If you come accross an API that requires an argument be passed NULL use 0

      I guess we're just going to disagree there and I don't even feel inclined to rationalize.

       
    • Amanda Wee

      Amanda Wee - 2006-01-03

      "NULL is defined as (void *)0 by the standard. In C++ it is no way the same as 0, but in both C and C++ 0 can be used in place of NULL."

      You're wrong. Refer to the C++ Standard (ISO/IEC 14882:2003) section 18.1, line 4:
      "The macro NULL is an implementation-defined C++ null pointer constant in this International Standard."

      A superscript at the end of that line leads to the note:
      "Possible definitions include 0 and 0L, but not (void*)0."

      Indeed, this is what Bjarne Stroustrup has to say about NULL and 0:
      "In C++, the definition of NULL is 0, so there is only an aesthetic difference. I prefer to avoid macros, so I use 0. Another problem with NULL is that people sometimes mistakenly believe that it is different from 0 and/or not an integer."

      This above quote is taken from:
      http://public.research.att.com/~bs/bs_faq2.html#null

       
    • Nobody/Anonymous

      There is a long FAQ on this here: http://www.xploiter.com/programming/c/cnull.shtml.

      As far as I've always understood NULL, it was a well defined address that did not point to anything.

      For all intents and purposes, it can be considered to be 0 - although, someone may come up with a processor achitecture in which 0x0000 is not the NULL address (hard to imagine).

      I am pretty sure there is a subtle distinction between C And C++ (maybe not anymore).

      Certainly, the FAQ (and other things I've read) seem to indicate that the compiler will automatically translate 0 in the context of a pointer into the NULL pointer value (whether it is actually 0 or not) - essentially, as far as I can gather, a kludge in the compiler to support centuries of bad programming practice ;-)

      So, much as I disapprove, I think it is probably safer to go with using 0 instead of NULL, since NULL seems to be relegated to the dust heap.

      rr

       
      • Thomas A. Moulton

        Well in a Memory Protected environment you could have NULL point to an illegal address so that if that pointer were accessed the processor would throw a HW exception...

        tom

         
    • Nobody/Anonymous

      heh.

      go ahead and read my post again. ill wait.

      laserlight:
      yea thats right i was contrasting the C standard with the C++ standard in those first two sentances. do you see now? no? well i dont particularly care. yea i may not have made that excruciatingly clear, but thats not really my problem nor does it add any weight against my argument.

      so in this case like it or not bjarne is wrong. more later.

      rr:
      the problem comes up more when interfacing c and c++ so you may or may not be right about a subtle difference. as for the kludge crack i think thats why vector bool exists as well.

      br5an:
      my point is at least to use 0 when either could be used. sorry if you disagree.

      everyone:
      note the warning with this code with the past few dozen versions of gcc and with several other compilers.

      include <cstdio>

      include <typeinfo>

      include <iostream>

      template <typename T> void TypeCheck(T)
      {
      std::cout << typeid(T).name();
      }

      int main()
      {
      TypeCheck(0);
      TypeCheck(NULL);
      }

      so then yea, the problem is that NULL is 0 but not really no. there is the standard and what compilers actually do and how they behave.

       
    • Nobody/Anonymous

      Just use 0.
      'NULL' is was useless purist abstraction.

      What about "-1"? ie All bits of the register set, as INVALID_HANDLE_VALUE in Windows is defined. That would be inefficient to check compared to zero: Sure, you'd reach the end of memory being able to access a byte at most, but you'd need a compare instruction with data of -1 (all bits set).

      Further.. Most processors store their vector tables starting at address 0 and up, so it's considered off limits by default. not to forget that some memory must be used to track memory allocations anyway. Anyway, the convention of using zero is efficient because the zero flag is set on a read by instructions on most processor, eliminating the need for a constant compare as with using -1 (all bits set) or other schemes.

      Same goes for 'bool'. Some wonder why it doesn't return 'all ones' ie filling the whole register with 1s. bool typically has 1 for true (or performs 'casting' to true for all non-zero values) and 0 for false. Again, if the value is 0 the zero flag is set, otherwise the zero flag is cleared and you have true condition. Same point as with a zero-value pointer. It's efficient that way. It's bs to abstract it with 'NULL'.

      So please, stop drowning in abstract bs. At least learn assembly language if you use C/C++, but Java is in its own world.

       
    • Amanda Wee

      Amanda Wee - 2006-01-03

      "I think it is probably safer to go with using 0 instead of NULL, since NULL seems to be relegated to the dust heap"
      I agree, though I have seen an argument otherwise in this thread, posted by Bubba:
      http://cboard.cprogramming.com/showthread.php?t=74072
      I dont intend to change my current practice though.

      "i was contrasting the C standard with the C++ standard in those first two sentances"
      If I remember correctly, the C Standard doesnt mandate that NULL be defined as (void)0, only that it be an implementation defined null pointer constant. The definition of NULL as (void)0 seems more of a prevalent C convention that was passed down to pre-standard C++.

      "yea i may not have made that excruciatingly clear, but thats not really my problem"
      Remember, you are giving advice to new programmers. Stating facts in an unclear way is a Bad Thing, especially when people could end up with misinformation.

      "so in this case like it or not bjarne is wrong"
      He isnt, since he is only speaking for C++.

      "note the warning with this code with the past few dozen versions of gcc and with several other compilers."
      The thing is, the warning given is a (good) attempt by the compiler to confirm that you arent doing something silly by mistaking a non-pointer for a pointer.

      By the way, would you like to login and post, or at least sign off? That way we can have an idea of who you are, and possibly credit you should we need to quote you.

       
      • Nobody/Anonymous

        "Remember, you are giving advice to new programmers. Stating facts in an unclear way is a Bad Thing"

        to right! i humbly submit that i should indeed have made things more clear. i apologize. i am serious and am not being a jerk here by the way.

        as for the compiler warning i did not say that it should not issue a warning. indeed it should. infact i use the various switches on my compilers to make sure that warnings are as errors. the point of this was for new programmers to code correctly, even if NULL is just conventionally 0, so that the compiler will not issue such a warning.

         
    • Chris Severance

      Chris Severance - 2006-01-03

      >I just DL'ed some source and received nearly four hundred "passing NULL to non-pointer type argument" errors.

      That's a feature not a bug. Thanks to the obvious noobness you knew to not trust any of it. Then you tell them to hide their noobistic ways by always using 0. Proper use of NULL and 0 helps me to know that code isn't noobbish. Looks like your code isn't going to pass noobster.

      >If you come accross an API

      As long as we stop before this we have good advice. The rest is bunk!

      >and most professional programmers

      Professional programmers don't scramble the standards for the noobs when there's no reason to do so. A book tells them one thing, you tell them another.

      >Only a fool would redefine NULL so it is completely safe and type safe to use 0 when an integer type or a pointer type is required

      Does that include fools who use systems where NULL is not 0?

      I have a better idea. Let's follow the standard where NULL is used with pointers and 0 is used with numbers, and in particular, if we're told to use NULL, we'll use it. It's what the help files, language, libraries, and books do and it's what the compiler likes best. This system isn't broken so it doesn't need fixing. Pop Quiz: Which ones are X and Y?

      CreateWindow(NULL,NULL,0,0,0,0,0,NULL,NULL,NULL,NULL);

      You 0 people will need to look it up. The rest of us have no cost hints built into the code. You're nuts if you think I'm going to throw those hints away. There's a lot of value in those two extra fingers.

      >As far as I've always understood NULL, it was a well defined address that did not point to anything.

      All pointers have a numeric value. 0 is chosen because noone has any purpose for that address and the OS can be set up to help debug programs that are improperly handling their pointers. If they do have a purpose, accessing *0 is only a pointer away.

      >someone may come up with a processor achitecture in which 0x0000 is not the NULL address

      NULL==0 has nothing to do with the processor. 0 is always a valid address though it may not be acceptable to read or write to it. NULL is chosen by the OS and compiler writers to whatever they want, most of the time 0.

      I don't see what the big problem is with macros. You use plenty when writing windows programs and it would be wrong to use literals so avoiding NULL and not writing your own macros doesn't make you a purist. Macros accomplish things easily that other tools can't. Macros often produce the best code and are available in C. To me, C++ is the main source of spagetti code.

       
      • Nobody/Anonymous

        "That's a feature not a bug."

        lol neat no one said it was a bug. nice catch.

        "Does that include fools who use systems where NULL is not 0?"

        for c++ it does cause bjarne requires that 0 be converted to a null pointer by the compiler. whatever the null pointer might be.

        "You 0 people will need to look it up."

        those who dont already know what the params to createwindow are sure.

        "0 is chosen because noone has any purpose for that address and the OS can be set up to help debug programs that are improperly handling their pointers."

        no 0 was chosen arbitrarily. *0 is readable and writeable on some hardware from asm.

        "I don't see what the big problem is with macros."

        lol!

        i can name several but most prevalent is that macros dont obay translation units.

        "Proper use of NULL and 0 helps me to know that code isn't noobbish."

        oh? this should be fun. given
        int * pi;

        which one of these is proper?
        if(!pi);
        // or
        if(pi != NULL);

         
        • Nobody/Anonymous

          I'm with Chris on this one.

          Use NULL if that's what the documentation tells you. Use 0 if that's what's in the documentation. If it fails, blame your supplier. :)

          As for your last question, the answer is: neither

          The most readable and correct method is to use:

          if(pi == 0) {/ handle it/} else {/ do it /}

          Cheers,

          Ian

           
      • Nobody/Anonymous

        if we were to take general math into account then NULL would always be without value where 0 would be valid.

         

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.