On enSO they wrote that NULL is (void *)0 .

But I don’t understand how the constant NULL is represented by a pointer to a void type?

Well, the code:

 #include "stdio.h" int main(void) { printf("%d\n",sizeof(NULL)); /// 8 return 0; } 
  • 2
    8 bytes is 64 bits? 64 bit system? Then what is wrong? - Sergey
  • @Sergey question is not about that =) - MaximPro
  • 2
    If C is valid, not C ++, then this is true: #define NULL ((void *) 0) The size of the pointer depends not so much on the system capacity as on the representation of the pointers. The pointer can contain only an offset in the segment or have a segment (selector) structure: offset. - paulgri
  • @paulgri you want to say that the size of the pointer does not depend on the intensity of the system? And I don’t understand the last sentence at all. What does it mean to contain only the offset? As far as I know the pointer contains the address. If you are talking about something more advanced then either tell the rest of it or give links to materials where you can read about it - MaximPro
  • @MaximPro, in general - yes. The pointer can be near (near) or far (far), it depends on the specific target platform, addressing methods in it, the memory model during compilation, etc. A similar question has already been, see the answers ru.stackoverflow.com/questions/574302/… - paulgri

3 answers 3

The sizeof operator has the size_t return type. Therefore, it is correct to specify the format specifier zu

 printf("%zu\n",sizeof(NULL)); ^^^^^ 

Otherwise, the printf function generally has an undefined behavior.

As for your question, according to the C language standard (6.3.2.3 Pointers)

If you want to see a pointer, it’s not necessary. it can be compared to any object or function.

and (7.19 Common de fi nitions)

3 The macros are

 NULL 

which expands to an implementation-de-fined null pointer constant ;

That is, the answer to your question follows from the definition of the constant null pointer constant and the definition of the macro NULL .

On your system, pointers include null pointer constants , which is usually defined in C as

 ( void * )0 

have a size of 8 bytes.

  • It turns out, sizeof NULL implementation defined and can be either the size of a pointer, or the size of an int? - Qwertiy
  • @Qwertiy NULL in C is defined as a pointer. Imagine the expression char c = 'A'; int x = (int) c; Does it follow from this that sizeof ((int) c) is 1? - Vlad from Moscow
  • You yourself have quoted: an integer pointer constant ..., NULL pointer expanding — that is, not instead of #define NULL (void*)0 it is forbidden to simply #define NULL 0 , as it is done in pluses. It turns out that sizeof NULL is equal to either sizeof (void*) or sizeof (int) (in the variant sizeof 0 ). What exactly is the error of such reasoning? Or is there still a significant piece of the standard that you did not include in the answer? - Qwertiy
  • @Qwertiy The words "cast to type void *" are key in this quote. In C ++, the null pointer constant is defined as simply an integer value. But nevertheless, the concept of null pointer value is defined there, which corresponds to the definition of the null pointer constant in C. That is, the coercion to an integer constant pointer is also used. That is, in C they combined both an integer constant and a cast to a pointer type into one concept. And in C ++ it was detailed and divided into two concepts. - Vlad from Moscow
  • " or such an expression cast to type void *" - here OR - i.e., either 0, or it, but reduced to void* . - Qwertiy

First, in C, NULL is either (void *) 0 or an integer constant 0 (just 0 , 0LL , 0LL , etc.) So there is no predetermined specific size for the result of a NULL expression in 0LL

Secondly, it is pointless to discuss the output of your code because of the attempts to print the sizeof result in %d . The result of sizeof is of type size_t , which is generally not compatible with the %d format specifier.

However, in any case, there would be nothing unusual if on your platform NULL were declared as (void *) 0 and the size of the result of such an expression would be 8 bytes. Therefore, it is not entirely clear what caused your question.

  • And what's wrong with outputting through% d? - MaximPro
  • @MaximPro The displayed value may not be accurate because. - αλεχολυτ
  • @alexolut yes, I understand, but for small numbers, what's the difference? - MaximPro
  • @MaximPro difference will be with a different order of bytes in particular. - αλεχολυτ
  • one
    @avp: For portability, there is a long time %zu for printing values ​​of type size_t . - AnT

At least in Visual C ++

 printf("%d\n",sizeof(NULL)); 

the same as

 printf("%d\n",sizeof(void*)); 

Accordingly, the displayed value depends on which code is compiled and what :)

So, Visual C ++ will give 4 when compiling a 32-bit application, and 8 when compiling a 64-bit application. Once again - the application , not the operating system .

Update
From Windows Kits -

 #ifndef NULL #ifdef __cplusplus #define NULL 0 #else #define NULL ((void *)0) #endif #endif 

So in C ++ mode in both versions, Visual C ++ will give out 4. But, since the tag was " c ", that's right ...

NULL is similarly described in Open Watcom.

Quote from "From the Handbook. Full description of the language":

A null pointer constant is an integer constant with a value of 0 , or a constant integer value of 0 , converted to a pointer type of void . NULL defined in stdlib.h , stdio.h and other header files.

Update 2
From the standard -
The macro NULL is defined in (and other headers) as a null pointer constant; see 7.17.

The macros are null pointer constant.

  • Comments are not intended for extended discussion; conversation moved to chat . - Nick Volynkin