2

In this question an initializer is used to set a pointer to null. Instead of using value of 0 value of 0L is used. I've read that one should use exactly 0 for null pointers because exact null pointer representation is implementation-specific.

Can using 0L to set a pointer to null cause problems while porting?

Community
  • 1
  • 1
sharptooth
  • 167,383
  • 100
  • 513
  • 979

9 Answers9

16

From the standard (4.10.1):

A null pointer constant is an integral constant expression (5.19) rvalue of integer type that evaluates to zero

so I guess 0L is ok.

Andreas Brinck
  • 51,293
  • 14
  • 84
  • 114
13

I think 0L is fine, except for the fact that it would imply that you believe the pointer type your assigning to is the same size as a long, and so is a bit confusing.

I think using NULL is much more clear.

KernelJ
  • 612
  • 3
  • 5
  • 1
    +1 because NULL is more clear to those maintaining the software. Trust me, I've seen deadbeef and 0 used in the same project. – wheaties Dec 15 '09 at 14:54
  • 4
    0xDEADBEEF is especially bad. 0 is the only value you can always set a pointer to be (a null pointer), and it doesn't matter what size the pointer is. – KernelJ Dec 15 '09 at 15:01
  • NULL is legal and idiomatic. 0 is legal and idiomatic. 0L is legal but not idiomatic. 0xDEADBEEF is either unspecified or undefined, and certainly isn't a null pointer constant. I'm looking forward to `nullptr` myself. – David Thornley Dec 15 '09 at 19:17
  • Seven characters for something which is basically a 0 is asking a bit much I think. I can't think why so much verbosity is required, when we have NULL already. Maybe it has some special uses in the new standard but I haven't really looked at it. – KernelJ Dec 16 '09 at 04:34
  • 1
    Overload resolution. Given `f(int)` and `f(int*)`, `f(NULL)` calls `f(int)` but `f(nullptr)` calls `f(int*)`. – MSalters Dec 16 '09 at 10:34
  • Yeah, that's great but... Anyone who overloads functions like that needs to be shot. – KernelJ Dec 16 '09 at 16:59
  • @KernelJ: `print(int)` and `print(char*)` is a perfectly reasonable overload. – dan04 Feb 16 '11 at 00:56
4

In C++0x there is a new null pointer constant called nullptr of type nullptr_t. It can be implicitly converted to any pointer type.

Until then I would recommend using NULL, however 0 and 0L will both work on every implementation I've ever heard of.

Brian R. Bondy
  • 339,232
  • 124
  • 596
  • 636
3

I can't give you an exact answer, but regardless of what the exact answer to your question is, just the idea itself of initializing a pointer with 0L is wrong, because it suggests that a pointer is the same size as a long, which is not necessarily true, ofcourse.

Whether the compiler accepts it or not, and whether it's safe or not, I wouldn't do it because it suggests an invalid idea.

Jesper
  • 202,709
  • 46
  • 318
  • 350
  • 3
    Does that mean that initialising it with 0 suggests it is the same size as an int? I don't think so. –  Dec 15 '09 at 14:52
  • No, because 0 does not imply an int. – dicroce Dec 15 '09 at 14:58
  • @Neil: Even if it does, it's less bad than explicitly saying `0L`, because the `L` strongly suggests that it's supposed to be understood as a `long`. Just `0` doesn't necessarily by itself imply that it's an `int`. – Jesper Dec 15 '09 at 15:04
  • I think the fact that you're explicitly saying the value is a long is the problem here. – KernelJ Dec 15 '09 at 15:05
  • @KernelJ: Yes, that's exactly what I mean. – Jesper Dec 16 '09 at 09:31
2

The null pointer representation is implementation specific, but neither 0 nor 0L is necessarily that implementation - they are just ways that the user can specify the null pointer, and either is OK.

I should point out that Bjarne Stroustrup has several times indicated that his preference is to use plain 0 (and not NULL).

  • 1
    He has, but in this case I disagree with him. It makes it a lot easier to find your pointer comparisons when you use NULL, instead of overloading 0 to mean either a) a pointer or b) a number. (Note: he recommends using nullptr when that's available, so he's conflicted on this point. He's not recommending 0 so much as recommending against using a macro.) http://www2.research.att.com/~bs/bs_faq2.html – Bill Dec 15 '09 at 15:35
2

I would disagree with those who recommend using NULL, though any of the three stated options would indeed work. In idiomatic C++, the standard choice is 0 (perhaps because that's Stroustrup's preference: http://www2.research.att.com/~bs/bs_faq2.html#null).

0L will be implicitly cast to the appropriate pointer type in the same way as 0 would be; it just looks a bit strange and doesn't really make a great deal of sense for the reason Jesper gave..

Nye
  • 459
  • 5
  • 7
2

You can use false, 0, 0l, 0L, 0ul, 0u, 00, or any number of ways to represent the literal zero. The literal zero is basically a magical symbol that happens to also correspond to a null pointer constant.

If we were talking about a value that happens to be bitwise zero and the code were memcpy-ing it over the pointer, then we would have the problems mentioned above.

Bonus question: What types have a null pointer constant that isn't bitwise zero?

MSN
  • 53,214
  • 7
  • 75
  • 105
1

I would have to agree with everyone that said NULL. To those that prefer using 0, my opinion is that your code should say what it means. The result you want is a null pointer, so your code should say that. It makes even more sense when you do a comparison:

if (some_variable == NULL) { ... }

is much clearer than

if (some_variable == 0) { ... }
-2

Assignment of 0L, a long integer (64bit) to an 32bit pointer might cause problems. As in the other post mentioned, use NULL to initializse pointers to zero.

codencandy
  • 1,701
  • 1
  • 10
  • 20
  • 1
    What problems do you refer to? AFAIK, the compiler will perform the required type conversions. – David Rodríguez - dribeas Dec 15 '09 at 15:03
  • 1
    The value 0 can be cast to any size of integer from any other. – KernelJ Dec 15 '09 at 15:04
  • You are not assigning "a long integer", but "the null pointer constant". And that is guaranteed to work, regardless of the bit width of integers or pointers. – jalf Dec 16 '09 at 00:28
  • All of you are right, my thinking was that assignment of 64 bit integers to a 32 bit pointer would be invalid. but as you mentioned the compiler will convert the constant to the required type. – codencandy Dec 16 '09 at 13:53