1

Occasionally, one reads that older C compilers had definitions of NULL that were not 0 or (void *)0. My understanding of the C standard was that even if the platform's bit pattern for a null pointer is nonzero, an integer 0 cast to a pointer (either implicitly or explicitly) is still a null pointer, and is stored internally as the platform's null pointer bit pattern.

But for example, here it is written:

In some older C compilers, NULL is variously defined to some weird things, so you have to be more careful with it.

I remember reading this in various other places from time to time. Unless this is a persistent urban legend, what other definitions of NULL have been in use?

ptomato
  • 56,175
  • 13
  • 112
  • 165
  • I'm pretty sure that some systems used `0L` in the bad old days before the C standard. – Jonathan Leffler Jun 30 '13 at 05:06
  • 2
    @CarlNorum: I don't think the questions are duplicate. The other one is looking at horrible non-conforming definitions (at least according to the example in the question), whereas this one would be well answered with conforming but unusual definitions. – R.. GitHub STOP HELPING ICE Jun 30 '13 at 05:15

2 Answers2

1

You are absolutely right when you are saying that null-pointer constant (constant integral zero or constant integral zero cast to void *) is guaranteed to be properly converted to the appropriate internal representation of null pointer for the target type. Which means that there's no need for any other definition of NULL. 0 or (void *) 0 will work everywhere.

However, at the same time, very early versions of C language did not make such guarantee and did not have a standard NULL macro. Assigning an integral value to a pointer variable caused the pointer to literally point to the address represented by that integral value. Assigning constant 0 to a pointer simply made it to point to address 0. If users wanted to have a reserved pointer value in their program, they had to manually choose a "throwaway" address to use for that purpose.

It is quite possible that macro NULL came into informal usage before the standardization of the language and before the aforementioned zero-to-pointer conversion rule came into existence. At that time NULL would have to be defined as an integral value representing that exact reserved address. E.g. a pre-standard C implementation that wanted to use address 0xBAADFOOD for null pointers would define NULL as 0xBAADFOOD. I can't confirm that though, since I don't know when exactly macro NULL first appeared "in the wild".

AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765
0

You're absolutely correct.

One of the "weird things" you might encounter is #define'ing NULL to ((void *)0), which would cause code that used NULL as anything but a pointer to fail.

Here are a few other variations:

http://www.tutorialspoint.com/c_standard_library/c_macro_null.htm

#define NULL ((char *)0)

or

#define NULL 0L

or

#define NULL 0

It's also worth noting that C++ 11 introduces nullptr to provide a type-safe disambiguation of NULL, 0, etc. Refer to Much Ado about Nothing, or (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1601.pdf

paulsm4
  • 114,292
  • 17
  • 138
  • 190
  • And having code that abuses `NULL` fail is excellent! – Jonathan Leffler Jun 30 '13 at 05:06
  • Here are some good arguments for using "0" instead of NULL: [What other definitions of NULL were there on older platforms?](http://www.gamedev.net/topic/277583-does-null-need-a-header-or-did-i-mess-something-up/?view=findpost&p=2727022) – paulsm4 Jun 30 '13 at 05:09
  • But having `char c = NULL;` generate a warning is better than letting it through uncommented upon. – Jonathan Leffler Jun 30 '13 at 15:49