Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt

Use this file to discover all available pages before exploring further.

A void pointer (void *), also known as a generic pointer, is a special pointer type in C that represents a raw memory address of an object or incomplete type without an associated data type. Because it lacks type information, the compiler does not know the size of the data it points to or how to interpret the bit pattern at that memory location.
void *ptr;

Type Compatibility and Assignment

In C, a void pointer can hold the address of any object type or incomplete type. The C standard allows implicit conversion between a void * and any other object pointer type, provided that type qualifiers are not discarded. You do not need to explicitly cast an unqualified typed pointer when assigning it to a void pointer, nor do you need to cast a void pointer when assigning it back to a typed pointer. However, strict ISO C dictates that void * is exclusively for object and incomplete types. Converting a function pointer to a void * is not permitted, as function pointers are not object pointers.
int integer_val = 42;
void *generic_ptr;

generic_ptr = &integer_val; // Valid: implicit conversion to void*
int *int_ptr = generic_ptr; // Valid: implicit conversion from void*

// void *func_ptr = &printf; // Invalid in strict ISO C: printf is a function

Type Qualifiers and const void *

When assigning a pointer to a generic void pointer, the destination pointer must possess at least the same type qualifiers (such as const or volatile) as the source pointer. Assigning a const-qualified pointer to a standard void * without an explicit cast drops the const qualifier, which is a constraint violation in standard C and will trigger a compiler diagnostic. To safely handle generic read-only memory, C provides the const void * type. This ensures that the immutability of the underlying data is preserved through the generic pointer interface.
const int read_only_val = 100;

// void *ptr = &read_only_val;       // ERROR: Discards 'const' qualifier
const void *cptr = &read_only_val;   // VALID: Qualifiers are preserved
const int *cint_ptr = cptr;          // VALID: Implicit conversion back to const int*

Dereferencing Restrictions

Because a void pointer lacks a specific data type, the compiler cannot determine the number of bytes to read or how to decode the data. Consequently, direct dereferencing of a void * or const void * is strictly prohibited and will result in a compilation error. To access the value stored at the memory address, the void pointer must first be cast to a pointer of the correct data type.
int value = 100;
void *ptr = &value;

// int result = *ptr;               // ERROR: Cannot dereference void*
int result = *(int *)ptr;           // VALID: Cast to int* before dereferencing

Pointer Arithmetic

The C standard defines pointer arithmetic based on the size of the pointed-to type. Since the void type is an incomplete type and has no defined size, pointer arithmetic (such as incrementing, decrementing, or adding offsets) on a void * is a constraint violation in strict ISO C. To perform arithmetic on a memory address held by a void pointer, it must be cast to a pointer type with a known size, typically a character pointer (char * or unsigned char *), which allows precise byte-level manipulation.
int array[5] = {10, 20, 30, 40, 50};
void *ptr = array;

// ptr++;                           // ERROR: Pointer arithmetic on void* is illegal in standard C
int next_val = *((int *)ptr + 1);   // VALID: Cast to int* allows arithmetic based on sizeof(int)

Memory Footprint and Representation

According to the C standard, a void * is guaranteed to have the exact same size, representation, and alignment requirements as a char *. However, the standard does not guarantee that a void * occupies the same amount of memory or uses the same internal representation as other object pointer types. While many modern flat-memory architectures implement all object pointers with a uniform size (e.g., 8 bytes on a 64-bit system), certain architectures (such as word-addressed machines) may use entirely different sizes and internal representations for different pointer types. Therefore, assuming a void * is universally the same size as an int * or any other specific object pointer is a portability flaw and incorrect under the C standard. Furthermore, because void * is strictly for object and incomplete types, its size and representation have no guaranteed relationship with function pointers.
Master C with Deep Grasping Methodology!Learn More