4

Which of the following methods is a more correct way to initialize a variable?

int x = 0;
int x = NULL;

What about the pointers? I have been told discordant things about NULL, like : "NULL is best for initializing pointers" or "Don't use NULL but 0 to initialize a variable" and so on... Now, I read on the internet that NULL is equal to 0 and I tested that myself. So what's the point? Why are some people saying that using NULL isn't a good choice? Is there something that I'm missing?

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
Claudio Cortese
  • 1,372
  • 2
  • 10
  • 21
  • 1
    `NULL` is not equal to `0`. – Iharob Al Asimi Jan 12 '16 at 21:49
  • This question is related to [this other question](http://stackoverflow.com/questions/9894013/is-null-always-zero-in-c) – Magix Jan 12 '16 at 21:50
  • http://stackoverflow.com/questions/8288482/is-null-in-c-required-defined-to-be-zero – bruceg Jan 12 '16 at 21:52
  • 1
    @iharob You say that `if ( 0 == NULL )` is not true? – i486 Jan 12 '16 at 21:54
  • @iharob that's strange, I initialized an integer variable to NULL and when I printed the value of the variable it was 0. – Claudio Cortese Jan 12 '16 at 21:55
  • 3
    That's not what I said, it's not necessarily `0`. – Iharob Al Asimi Jan 12 '16 at 21:56
  • The `NULL` macro will always be zero-valued, although it may be a naked `0`, or `(void *) 0`, or some other integer expression that evaluates to `0`. – John Bode Jan 12 '16 at 21:57
  • @iharob how can this be possible? I'm sorry if I'm missing something, I'm new to C and programming in general – Claudio Cortese Jan 12 '16 at 21:58
  • @JohnBode: Not true. See [my answer](http://stackoverflow.com/a/34754532/198536) below. – wallyk Jan 12 '16 at 21:59
  • @i486: `NULL` is a macro. And for many C implementations, it is `#define NULL ((void *)0)`. `0` is an integer. Thus the pointer `(void *)0` is converted to an `int` before the compare. That is already implementation defined and will fail (i.e. undefined behaviour) on typical 64 bit and other systems where `int` has less bits than a pointer. – too honest for this site Jan 12 '16 at 22:00
  • 1
    @wallyk: Yes true - [N1570](http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf), 6.3.2.3/3 and footnote 66. A null pointer *constant* (which `NULL` is defined to be) is always zero-valued. After translation, the corresponding null pointer *value* may or may not be zero-valued. – John Bode Jan 12 '16 at 22:05
  • @Olaf If you compare 32-bit `0` and 64-bit `0` the comparison will be positive, I think. Is it true? – i486 Jan 12 '16 at 22:09
  • @i486: `(void *)0` The standard is a bit [ambiguous](http://port70.net/~nsz/c/c11/n1570.html#6.3.2.3p3) here. It allows `0` alone as _null pointer constant_ (NPC) and state that "If a null pointer constant is converted to a pointer type, the resulting pointer, called a null pointer ...". Problem is it also allows `(void *)0` as NPC, which also is also a _null pointer_ due to the "cast to pointer" (`void *` is not excluded here). I prefer to take the _null pointer_ view, so that construct would already be allowed not to be all-zero. But that might be disputable. – too honest for this site Jan 12 '16 at 22:37
  • @i486: Anyway, not providing a specific token for a _null pointer constant_ like Pascal, Modula (`NIL`) was one of the worst decissions in early C. C++ finally corrected this with `nullptr` - too bad the C commitee was not that brave. – too honest for this site Jan 12 '16 at 22:40
  • NIL? I tried to print the value of a pointer initialized with NULL and it was (nil) – Claudio Cortese Jan 12 '16 at 22:43
  • 1
    @ClaudioCortese: From the C standard (C11 n1570): "The argument shall be a pointer to void. The value of the pointer is converted to a sequence of printing characters, **in an implementation-defined manner**." (emphasise mine). FYI: `NIL` means "Not In List". For list-based languages like LISP ("ListProcessing"), the name instantly becomes clear. Note that the libraries might not only be used by the C or the C++ language, but also e.g. by Pascal programs. Some libraries might just print the value, e.g. `0x0`, others e.g. `(null)`. AFAIK none prints uppercase `NULL` - likely for good reasons. – too honest for this site Jan 13 '16 at 09:11

7 Answers7

5

NULL is a pointer constant. You use this to initialize a pointer to a value that says it doesn't point to anything.

On most C implementations, it is defined as:

#define NULL ((void *)0)

But there's no guarantee of that.

dbush
  • 205,898
  • 23
  • 218
  • 273
  • Maybe that's why a lot of people told me that's not a good idea to use NULL? This could explain the mistery for me – Claudio Cortese Jan 12 '16 at 21:56
  • 1
    @ClaudioCortese Exactly. In practice, they're usually the same, but if you depend on this behavior and then move your code to a platform where there's not, you'll have all kinds of problems. – dbush Jan 12 '16 at 21:57
  • Mhh, ok, so it's more a thing related to the portability of the code that something else, right? – Claudio Cortese Jan 12 '16 at 22:01
  • 1
    @ClaudioCortese Right. Always make your code portable, unless you have very specific reasons not to. – dbush Jan 12 '16 at 22:02
  • So the same apply to pointers, if want to declare and initialize a pointer i would do *pointer = 0 and not *pointer = NULL for portability reason, right? – Claudio Cortese Jan 12 '16 at 22:09
  • 1
    @ClaudioCortese No, you *always* initialize a pointer with NULL, i.e. `int *pointer = NULL`. – dbush Jan 12 '16 at 22:15
  • OK, why? Is there a reason? I tried to print the address of a pointer, prior initializing it with NULL and then with 0, and the results were the same – Claudio Cortese Jan 12 '16 at 22:20
  • 1
    As I mentioned before, NULL is *usually* 0, but not always. So always use NULL for pointers. – dbush Jan 12 '16 at 22:22
4

Which of the following methods is a more correct way to initialize a variable?

// int x = NULL;  `NULL` implies pointer
int x = 0;        // 0 implies integer value and x is an integer.

What about the pointers?

void *p = NULL;  // `NULL` implies pointer and p is a pointer.
//void *p = 0;   // 0 implies integer value

that NULL is equal to 0

It is equal in value, though maybe not in bit pattern. See below +0.0, -0.0 example.


If NULL was equal to 0, always, then there would not be a need for it in C.

NULL is a null pointer consonant - it often, but does not always have a bit pattern of zeros. A pointer with a NULL value will always compare equally to 0: same value, different bit patterns.

Remember that == compares values, not bit patterns.

void *a = NULL;
if (a == NULL) Always_True();
if (a == 0) Always_True();

Example that may help. +0.0 and -0.0 have the same value, same type, but different bit patterns. Similar thing may happen with pointers.

int main(void) {
  double pz = +0.0;
  double nz = -0.0;
  printf("=:%d  bits:%d\n", pz == nz, memcmp(&pz, &nz, sizeof pz) == 0);  // =:1  bits:0
  return 0;
}
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
2

NULL is a null-pointer constant. You should use that to initialize pointer types.

From C11, chapter §7.19, stddef.h

NULL
which expands to an implementation-defined null pointer constant.

and for null-pointer constant in C, chapter §6.3.2.3

An integer constant expression with the value 0, or such an expression cast to type void *, is called a null pointer constant.[...]

So, the type is that of a pointer.

For other non-pointer variables, you should be using 0.

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
  • Is there a real reason behind that or it's just a "personal preference"? – Claudio Cortese Jan 12 '16 at 21:57
  • @ClaudioCortese Which one is personal preference? The type matters. Maybe most of the cases, the implementation is _equivalent_, but it's just not the _same_. Hope it's clear. :) – Sourav Ghosh Jan 12 '16 at 21:58
  • I mean, if NULL == 0, why is ok to initialize pointers with NULL and why it's not ok initializing variable with NULL? – Claudio Cortese Jan 12 '16 at 22:03
  • 1
    @ClaudioCortese it is _most likely_ that `NULL` == `0`, but that's not guranteed. Please notice the _"implementation-defined"_ part in my answer. – Sourav Ghosh Jan 12 '16 at 22:05
1

Don't use NULL for initializing non-pointer types, as it may expand to something like (void *) 0 depending on the implementation. Use plain 0 (or a macro or const-qualified variable that evaluates to plain 0) for integral types.

John Bode
  • 119,563
  • 19
  • 122
  • 198
1

Definitely use NULL when you're initializing (or comparing) a pointer; it's good style.

Definitely don't use NULL when you're working with integers; it's poor style (and it might very well not work.)

Don't listen to anyone suggesting that you shouldn't use NULL with pointers; they're probably confused.

See the C FAQ list at http://c-faq.com/null/index.html for more information.

Steve Summit
  • 45,437
  • 7
  • 70
  • 103
-1

Theoretically NULL can be pointer to address different from 0. But in practice such definition will crash large percent of software. And it is 0 (or (void *)0) in 99.99% of cases.

i486
  • 6,491
  • 4
  • 24
  • 41
-1

There are/were some architectures deployed for which NULL is not zero: Prime 50, Honeywell-Bull, CDC Cyber 180 series and others. In these cases, NULL is most definitely not interchangeable with zero.

See this answer to another question for details of the machines affected.

Community
  • 1
  • 1
wallyk
  • 56,922
  • 16
  • 83
  • 148
  • 1
    Are we talking about the null pointer *constant* or the null pointer *value*? As far as C is concerned, the null pointer constant is *always* zero-valued. – John Bode Jan 12 '16 at 21:58
  • @JohnBode: Yes, it is always a good idea to differentiate between `NULL` (macro), a _null pointer_ and a _null pointer constant_. – too honest for this site Jan 12 '16 at 22:04
  • To the point: wallyk's answer is misleading; `NULL` would typically be defined as some version of 0 *even* *on* those baroque old machines where null pointers weren't 0. See the C FAQ list, question 5.5. – Steve Summit Jan 12 '16 at 23:19