What Is a Void Pointer and What Is a Null Pointer

What's the difference between a null pointer and a void pointer?

Null pointer is a special reserved value of a pointer. A pointer of any type has such a reserved value. Formally, each specific pointer type (int *, char * etc.) has its own dedicated null-pointer value. Conceptually, when a pointer has that null value it is not pointing anywhere.

Void pointer is a specific pointer type - void * - a pointer that points to some data location in storage, which doesn't have any specific type.

So, once again, null pointer is a value, while void pointer is a type. These concepts are totally different and non-comparable. That essentially means that your question, as stated, is not exactly valid. It is like asking, for example, "What is the difference between a triangle and a car?".

What is a void pointer and what is a null pointer?

The two concepts are orthogonal:

  1. A void pointer, (void *) is a raw pointer to some memory location.
  2. A null pointer is a special pointer that doesn't point to anything, by definition. It can be a pointer to any type, void or otherwise.

A void pointer can be null or not:

void *void_ptr1 = nullptr;
void *void_ptr2 = malloc(42);
void *void_ptr3 = new Foo; // void * can point to almost anything
void *void_ptr4 = (char*)void_ptr3 + 1; // even somewhere inside an object

A non-void pointer can also be null or not:

Foo *f = nullptr;
Foo *g = new Foo;

Can we call (void *)0 a void pointer in C?

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 );

What is the difference between a null pointer constant (nullptr), a null pointer value and a null member pointer value?

What is the difference between a null pointer constant (nullptr), a null pointer value and a null member pointer value?

Null pointer constant is either nullptr (or any other prvalue of type std::nullptr_t), or integer literal of value 0. Examples of null pointer constants:

NULL  // a macro for one of the others
0
0L
nullptr

std::nullptr_t fun();
fun() // also a null pointer constant

Of these, don't use the integer literals nor NULL unless you need to support older than C++11 standard.

Null pointer value is the value of a pointer type that represents null. Examples of null pointer values:

(void*)nullptr     // pointer to void
(int*)nullptr // pointer to object

using void_fun = void();
(void_fun*)nullptr // pointer to function

Null member pointer value is the value of a member pointer type that represents null. Example of null member pointer values:

(int some_class::*)nullptr // pointer to data member

using mem_void_fun_ptr = void(some_class::*)(); // unfortunately cannot alias member
// function type as far as I know,
// so we alias pointer to it instead
(mem_void_fun_ptr)nullptr // pointer to member function

Note that std::nullptr_t is not a pointer type nor a pointer to member type.

What does this mean: a pointer to void will never be equal to another pointer?

TL/DR: the book is wrong.

What am I missing?

Nothing, as far as I can see. Even the erratum version presented in comments ...

A pointer to void will never be equal to another pointer to void.

... simply is not supported by the C language specification. To the extent that the author is relying on the language specification, the relevant text would be paragraph 6.5.9/6:

Two pointers compare equal if and only if both are null pointers, both
are pointers to the same object (including a pointer to an object and
a subobject at its beginning) or function, both are pointers to one
past the last element of the same array object, or one is a pointer to
one past the end of one array object and the other is a pointer to the
start of a different array object that happens to immediately follow
the first array object in the address space.

void is an object type, albeit an "incomplete" one. Pointers to void that are valid and non-null are pointers to objects, and they compare equal to each other under the conditions expressed by the specification. The usual way that such pointers are obtained is by converting an object pointer of a different (pointer) type to void *. The result of such a conversion still points to the same object that the original pointer did.

My best guess is that the book misinterprets the spec to indicate that pointers to void should not be interpreted as pointers to objects. Although there are special cases that apply only to pointers to void, that does not imply that general provisions applying to object pointers do not also apply to void pointers.

How to check if void pointer points to NULL?

I'd simply write if (!ptr).

NULL is basically just 0 and !0 is true.

Is NULL data-pointer the same as NULL function-pointer?

C 2018 6.3.2.3 4 says:

Conversion of a null pointer to another pointer type yields a null pointer of that type. Any two null pointers shall compare equal.

This paragraph, unlike paragraph 7, does not limit the conversions to pointers to object types or pointers to function types. Therefore, if a null pointer of some pointer-to-function type is converted to void *, the result is a null pointer, and then applying ! to it yields 1.

Establishing the converse, that if applying ! to a pointer yields 1, it necessarily arose from a null pointer, it more difficult. We could imagine some non-null function pointer that, when converted to void *, yields a null pointer. Considering the intent of POSIX to allow function pointers to be temporarily stored in void *, we can conclude that converting a pointer to a function to void * should never result in a null pointer.

Could the bit pattern for a NULL void* data-pointer ever equate to a non-NULL function-pointer value?

The C standard does not discuss the bit patterns used to represent pointers. The semantics are established in terms of the values.

Would any sane implementation do this?

Certainly bare-metal boot code on some hardware might put executable instructions at address zero and call a function there for some reason and might also use address zero as a null pointer. It will simply be designed not to depend on that function at address zero not being tested for being a null pointer.

Outside of such special situations, i.e., for all practical purposes, this is not done. If some software decides it needs a special representation for a null pointer, it will set aside some address for that and not use that address for any ordinary function or object.



Related Topics



Leave a reply



Submit