5

Summarizing the C standard, specifically ISO/IEC 9899:201x §6.3.2.3 - 3:

If a pointer is being compared to the constant literal 0, then this is a check to see if the pointer is a null pointer. This 0 is then referred to as a null pointer constant. The C standard defines that 0 cast to the type void * is both a null pointer and a null pointer constant.

Now if we look at (void *)0 it is an address(illegal in this context) that is pointing to void.

Normally we can cast such an address to any appropriate pointer datatype and dereference it but here even after casting it to some other pointer type it is illegal to dereference it.

So my doubt is:

Can we call (void *)0 as a void pointer looking the way it is defined?

Also see the below code:

void *pointer = NULL;

What will I call it now? A void pointer, a null pointer or a null void pointer?

anastaciu
  • 23,467
  • 7
  • 28
  • 53
LocalHost
  • 910
  • 3
  • 8
  • 24
  • What do you mean by "illegal in this context". What context? Also, you quote a block of text that refers to the C standard, but it's not from the standard itself. Where is it from? – Keith Thompson Oct 19 '20 at 09:51
  • I don't have time to post a full answer right now, so I'll just mention that it's important to distinguish between source code constructs (like a *null pointer constant*) and things that exist during program execution (like a null pointer **value**). – Keith Thompson Oct 19 '20 at 09:53
  • I mean to say you can't really de reference a null pointer but can suitably do so with some other pointer(not void). – LocalHost Oct 19 '20 at 09:53
  • If you cast the pointer you might change its type, but you don't change its value. Therefore, even though it's no longer a void pointer, it is still a NULL pointer, which can't be dereferenced. – Felix G Oct 19 '20 at 09:55
  • I have no idea what you are quoting but it isn't the C standard. Are you quoting yourself or something? – Lundin Oct 19 '20 at 10:52
  • @Lundin Yes i summarized it. Actual point is section 6.3.2.3 Pointers, paragraph 3 – LocalHost Oct 19 '20 at 11:09

3 Answers3

6

What will i call it now ? A void pointer, a null pointer or a null void pointer ?

In this declaration

void *pointer = NULL;

there is declared a pointer of the type void * that is a null pointer due to initializing it with a null pointer constant.

A pointer to object of any type can be a null pointer.

The casting of the zero integer constant to void * is used because a pointer of the type void * can be implicitly converted to any other object pointer type. Another advantage of using the type void * is that you may not dereference a pointer of that type because the type void is always an incomplete type.

Early versions of C did not have the type void. Instead of the type void there was used the type char. So for example in old C programs you can encounter something like the following

memcpy( ( char * )p1, ( char * )p2, n );
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • and what about `(void *)0` ? Will it be a void pointer or just a null pointer ? – LocalHost Oct 19 '20 at 09:57
  • @LocalHost It is a null pointer constant. From the C Standard "An integer constant expression with the value 0, or such an expression cast to type void *, is called a null pointer constant" – Vlad from Moscow Oct 19 '20 at 09:58
  • That's exactly my doubt. Why it can't be void pointer ? Aren't the void pointers declared the same way? – LocalHost Oct 19 '20 at 10:00
  • 2
    Both, it is a `null pointer` of type `void*`. You have to understand that 'void pointer' and 'null pointer' are orthogonal concepts, so any pointer can be void, null, both or none (`(int *)0` for example is a non-void null pointer). – Felix G Oct 19 '20 at 10:01
  • 2
    @LocalHost A null pointer can be a pointer to an object of any type. not only of the type void *. – Vlad from Moscow Oct 19 '20 at 10:02
  • 1
    Also, the reason you can't dereference a pointer is different for void and null. A void pointer can't be dereferenced because that would produce a value of type `void`, but void is the absence of a type. On the other hand a null pointer (of any type) can't be dereferenced because that would cause undefined behavior. Dereferencing a void pointer won't even compile, while dereferencing a null pointer might compile, but possibly crash during execution. – Felix G Oct 19 '20 at 10:05
  • 1
    @LocalHost In fact a null pointer constant could be an integer constant casted to any object type. For example in first versions of C there was not the type void. Instead of it there was used the type char. But the advantage of using the type void is that it is implicitly converted to any object pointer type. – Vlad from Moscow Oct 19 '20 at 10:08
  • 1
    But `(void*)0` is a special item, a null pointer constant. It can explicitly be used together with function pointers, which is normally not the case with void pointers. – Lundin Oct 19 '20 at 14:06
4

So my doubt is can we call (void *)0 as a void pointer looking the way it is defined ?

It is certainly a void pointer. The declaration void *pointer means that you declare pointer as a pointer to void. pointer will never be anything else than a void pointer. It's type will never change, but the value can change from null to something else. Also, the expression (void *)x basically mean "cast x to a void pointer`. So this expression also has the type pointer to void.

What will i call it now ? A void pointer, a null pointer or a null void pointer?

I would never use the phrase "null void pointer". A null pointer is a pointer of any type, pointing at null. A void pointer is simply a pointer pointing to void. Combining them to one phrase would only call confusion. It is both a void pointer and a null pointer. Any pointer can be a null pointer. Consider this:

int *p = (void*)0;

p is a null pointer, but it's not a void pointer.

klutt
  • 30,332
  • 17
  • 55
  • 95
4

So my doubt is can we call (void*)0 as a void pointer looking the way it is defined?

(void*)0 is a null pointer constant not a void pointer.

The casted assignment does not define the type of the variable. For example in int *ptr = (void*)0;, ptr is an int pointer, i.e. a pointer to int, regardless of the assignment, the same way that void *ptr = (void*)0; is a void pointer, i.e. a pointer to void, both these pointers value is 0 which makes them both null pointers.

Read Lundin's comment bellow for interesting extra info about (void*)0.


void *pointer = NULL;

What will I call it now ? A void pointer, a null pointer or a null void pointer ?

A null pointer is a pointer whose value is 0.

A void pointer is a pointer that has void type.

a null void pointer is a pointer of type void and its value is 0, it's not a conventional expression but rather a description of what the pointer is and its value (i.e the memory address where it's pointing to, if defined).

So IMO you can call it all three, deppending on what you want to refer to or the description you are asked for.

A null pointer can't be dereferenced being void or whatever other type. Its value is 0, it doesn't point to any valid memory location and that is the only reason why you can't dereference it.


For completion, these are all valid statements and will produce the same outcome:

void *pointer = (void*)0;
void *pointer = 0;
void *pointer = NULL;

NULL can be defined as (void*)0 (null pointer constant), or just 0 (constant literal), both are valid.

anastaciu
  • 23,467
  • 7
  • 28
  • 53
  • 2
    `(void*)0` specifically is a null pointer constant. As such, it is a special item in the C language. For example, pointer compatibility checks turn more lax and you may even use it together with function pointers. Whereas a void pointer pointing at an address is a generic _object_ pointer, with slightly tighter compatibility rules (other pointer must have same or less type qualifiers, must be an object pointer etc). – Lundin Oct 19 '20 at 14:03