2

Below there is a small program which I came across and thought to search more on it. It gives a warning: comparison between pointer and integer

 if ( NULL == '\1' )

I'm just unable to figure out that which one is pointer and which one is integer and more important why so?

I can just say that NULL is pointer here but don't know why so?

Yes, one more thing is there when we replace the NULL with '\0' then there is no compilation warning. Why?

The full code is :-

#include <stdio.h>
int main()
{
    if ( NULL == '\1' )
    {
       printf (" \nTrue "); 
    }
    else
    {
        printf (" \nFalse");
    }
    return 0;
}
Amit Upadhyay
  • 7,179
  • 4
  • 43
  • 57

4 Answers4

3

NULL is a null pointer constant. It's typically defined as:

#define NULL 0

or

#define NULL ((void *)0)

Based on the warning message you get, it looks like your implementation has the latter definition.

Hence, the comparison produces the warning message as you are comparing a pointer and an int. Character literals are of type int in C.

Yes, one more thing is there when we replace the NULL with '\0' then there is no compilation warning. Why?

That's because comparing an int ('\0') with another int ('\1') is fine.

Amit Upadhyay
  • 7,179
  • 4
  • 43
  • 57
P.P
  • 117,907
  • 20
  • 175
  • 238
  • Wrong. In C++ (tag on the question) NULL CAN NOT be defined as `(void*)0` – SergeyA Dec 07 '15 at 19:29
  • Sorry, I didn't notice C++ tag (I follow C tag). Besides, the code looks like C code and title says C. Perhaps, the C++ tag needs to go. – P.P Dec 07 '15 at 19:31
  • Agree, one of those is misplaced, but I do not know which one :) – SergeyA Dec 07 '15 at 19:32
2

Well you can only compare things that are comparable in nature. Integers and addresses are too different to be comparable; integers are values, while addresses are pointers to values, their usages are too different to consider them comparable.

NULL is defined as ((void *)0) which is a special constant for pointers that denotes a pointer that never points to something... It is typed as a pointer. void * is the universal type for pointers.

\1 is a constant for char (it is the character of index 1 in the ASCII table, it is known as SOH char). A char is roughly a number that can be easily translated to a char when printed. You literal is 1 typed as a char, but for efficiency, in almost all arithmetic and comparison expressions, every such char is converted to an int.

So you basically compare a pointer to an int as the compiler says. This is not strictly forbidden, but the compiler as usual has a serious doubt about this and warns you. Effectively, you expression has no sense.

If you really want to compare both (again probably non sense), then you can either:

  1. convert the pointer to an int (this is dangerous as you surely lose information in that conversion) : `((int)NULL) == '\1',
  2. convert the literal value to a pointer (less dangerous but also stupid) : `NULL == (void *)'\1'
Jean-Baptiste Yunès
  • 34,548
  • 4
  • 48
  • 69
  • 1
    This question was just for gaining more information about the NULL and '\0' not for creating any stupidity –  Dec 07 '15 at 19:41
  • I know. Sorry if *stupid* is the wrong word, I'm not English native, I may make some misuse; forgive me if it is so. – Jean-Baptiste Yunès Dec 07 '15 at 19:43
1

NULL, 0 and '\0' have a slightly different meanings. See here for more information. NULL is designt to be the null pointer while 0 is a constant literal of the integer 0. You can use constant literals of the the integer 0 for pointers too. Thay have some special meaning in such situations. This mean you can use 0 in all such situations but NULL should only be used for pointers. If you would have an integer which is not 0, it would not make much sense to compare it with a pointer. Remember, while using C/C++, you don't know how pointers are represented at the hardware.

In C NULL is often implemented as ((void*)0). In C++ it may be implemented as 0.


If you write NULL == 0 in C, you are comparing an integer with a pointer. Since 0 is a constant literal for the integer 0, it has a special meaning and doesn't generate any warning or error. But if you have another integer there, maybe 1, it does not make much sense to compare it with NULL.

Community
  • 1
  • 1
JojOatXGME
  • 3,023
  • 2
  • 25
  • 41
0

It only really makes sense to compare NULL to memory addresses. 1 is clearly not a meaningful memory address but 0 is a commonly referenced memory address. If you are comparing NULL to any non-pointer value other than 0, it is highly suggestive of a logic error, and that's why you get a warning.

Perhaps you were thinking of the unofficial-but-common macro NUL which is defined as '\0'.

QuestionC
  • 10,006
  • 4
  • 26
  • 44