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.