4
#include <stdio.h>

int main(){
 int *p = '\0';
 if (p == NULL){
   // this block will get executed.
 }
 return 0;
}

I have read that 0, NULL and \0 are all equal to the integer constant 0 in C. So is the above code technically correct in setting and checking for a NULL pointer? I guess it still needs to be avoided as \0 is mainly used to terminate strings and its usage here is confusing?

Dan
  • 2,694
  • 1
  • 6
  • 19
  • I think the answer is yes: the character constant `'\0'` is an integer constant whose value is zero, therefore it is valid as a null pointer constant. So `int *p = '\0';` should indeed initialize `p` to a null pointer. I feel like I have seen this question on this site before but haven't found a duplicate yet. In any case it is certainly terrible stylistically. – Nate Eldredge Jun 07 '21 at 00:28
  • 2
    The macro `NULL` was created because not all hardware at the time used "zero" as a null pointer. C adopted the "integer zero to mean null pointer" concept from C++ much later. – Some programmer dude Jun 07 '21 at 00:34

3 Answers3

2

'\0' is an integer zero.

All three do exactly the same.

int *p = NULL;
int *p = 0;
int *p = '\0'; 

but the last two may emit the warning.

Jabberwocky
  • 48,281
  • 17
  • 65
  • 115
0___________
  • 60,014
  • 4
  • 34
  • 74
1

The best way to describe is that a pointer can be a zero, indicating its functionally pointing to nothing (which isn't true: it's actually pointing at memory spot zero). But there are many ways to represent a zero, and NULL is one of those ways. So technically, any way you write the zero is technically legally as long as the compiler interprets it as "zero".

FYI, some people write if statements in reverse to protect against an accidental assignment if you forget an equal sign:

if (NULL == p){
Wes Hardaker
  • 21,735
  • 2
  • 38
  • 69
  • `if (NULL == p) {` is no longer useful and rather ugly IMHO, modern compilers with the proper warning level will emit a warning for `if (p = NULL) {`. One can also write `if (!p) {` – chqrlie Jun 07 '21 at 12:08
  • That is true, unless you're writing code for nearly all compilers (which the open source package we develop is indeed targeting), and I've found way way too many developers that ignore warnings (sigh). Hence the reason its not allowed in some languages (e.g. python), as frustrating as that is too. – Wes Hardaker Jun 07 '21 at 15:46
  • More frustrating to me is the lack of `i++` in Python. Developers who ignore warnings or fail to enable them deserve the agony of searching for stupid bugs hiding in plain sight. Even when cross-compiling with clunky compilers it is feasible to add an lint target using proper tools. Your photos are awesome :) – chqrlie Jun 07 '21 at 19:32
  • TOTALLY agree. Awww... thanks so much for the photos comment! – Wes Hardaker Jun 08 '21 at 03:09
-6
int *p = '\0';

Tells p is an integer pointer and points to a character that is numerically zero. The compiler will convert this character to a numerical literal for you, may give a warning about it. As you have not allocated memory for p to point to, this might give you a segfault. In p == NULL, you're not comparing what p points to (any value that you might assign), but the value of p itself, that is the address that the pointer points to.