Can I use NULL as substitution for the value of 0?

Am I allowed to use the NULL pointer as replacement for the value of 0?

Or is there anything wrong about that doing?


Like, for example:

int i = NULL;

as replacement for:

int i = 0;

As experiment I compiled the following code:

#include <stdio.h>

int main(void)
{
    int i = NULL;
    printf("%d",i);

    return 0;
}

Output:

0

Indeed it gives me this warning, which is completely correct on its own:

warning: initialization makes integer from pointer without a cast [-Wint-conversion] 

but the result is still equivalent.


  • Am I crossing into "Undefined Behavior" with this?
  • Is it permissible to utilize NULL in this way?
  • Is there anything wrong with using NULL as a numerical value in arithmetical expressions?
  • And what is the result and behavior in C++ for this case?

I have read the answers of What is the difference between NULL, '\0' and 0 about what the difference between NULL, \0 and 0 is, but I did not get the concise information from there, if it is quite permissible and also right to use NULL as value to operate with in assignments and other arithmetical operations.


Solution 1:

Am I allowed to use the NULL pointer as replacement for the value of 0?

No, it is not safe to do so. NULL is a null-pointer constant, which could have type int, but which more typically has type void * (in C), or otherwise is not directly assignable to an int (in C++ >= 11). Both languages allow pointers to be converted to integers, but they do not provide for such conversions to be performed implicitly (though some compilers provide that as an extension). Moreover, although it is common for converting a null pointer to an integer to yield the value 0, the standard does not guarantee that. If you want a constant with type int and value 0 then spell it 0.

  • Am I might crossing into Undefined Behavior with this?

Yes, on any implementation where NULL expands to a value with type void * or any other not directly assignable to int. The standard does not define the behavior of your assignment on such an implementation, ergo its behavior is undefined.

  • is it permissible to operate with the NULL in that way?

It is poor style, and it will break on some systems and under some circumstances. Inasmuch as you appear to be using GCC, it would break in your own example if you compiled with the -Werror option.

  • Is there anything wrong about to use NULL as numerical value in arithmetical expressions?

Yes. It is not guaranteed to have a numerical value at all. If you mean 0 then write 0, which is not only well defined, but shorter and clearer.

  • And how is the result in C++ to that case?

The C++ language is stricter about conversions than is C and has different rules for NULL, but there, too, implementations may provide extensions. Again, if you mean 0 then that's what you should write.

Solution 2:

NULL is some null pointer constant. In C it could be an integer constant expression with value 0 or such an expression cast to void*, with the latter more likely. Which means you can't assume to use NULL interchangeably with zero. For instance, in this code sample

char const* foo = "bar"; 
foo + 0;

Replacing 0 with NULL is not guaranteed to be a valid C program, because addition between two pointers (let alone of different pointer types) is not defined. It will cause a diagnostic to be issued due to a constraint violation. The operands for addition will not be valid.


As for C++, things are somewhat different. Lack of an implicit conversion from void* to other object types meant that NULL was historically defined as 0 in C++ code. In C++03, you could probably get away with it. But since C++11 it can legally be defined as the nullptr keyword. Now again producing an error, since std::nullptr_t may not be added to pointer types.

If NULL is defined as nullptr then even your experiment becomes invalid. There is no conversion from std::nullptr_t to an integer. That is why it is considered a safer null pointer constant.

Solution 3:

Am I allowed to use the NULL pointer as a replacement for the value of 0?

int i = NULL;

The rules vary between languages and their versions. In some cases you can and in others, you can't. Regardless, you shouldn't. If you're lucky, your compiler will warn when you attempt it or even better, fail to compile.

In C++, prior to C++11 (quote from C++03):

[lib.support.types]

NULL is an implementation-defined C++ null pointer constant in this International Standard.

It makes little sense to use a null pointer constant as an integer. However...

[conv.ptr]

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

So, it would technically work even if it's nonsensical. Due to this technicality, you may encounter poorly written programs that abuse NULL.

Since C++11 (quote from latest draft):

[conv.ptr]

A null pointer constant is an integer literal ([lex.icon]) with value zero or a prvalue of type std​::​nullptr_­t.

A std​::​nullptr_­t is not convertible to an integer, so using NULL as integer would work only conditionally, depending on choices made by the language implementation.

P.S. nullptr is a prvalue of type std​::​nullptr_­t. Unless you need your program to compile in pre-C++11, you should always use nullptr instead of NULL.


C is a bit different (quotes from C11 draft N1548):

6.3.2.3 Language / Conversions / Other operands / Pointers

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 case is similar to post C++11 i.e. the abuse of NULL works conditionally depending on choices made by the language implementation.