Pointer arithmetic for void pointer in C

CVoid PointersPointer Arithmetic

C Problem Overview


When a pointer to a particular type (say int, char, float, ..) is incremented, its value is increased by the size of that data type. If a void pointer which points to data of size x is incremented, how does it get to point x bytes ahead? How does the compiler know to add x to value of the pointer?

C Solutions


Solution 1 - C

Final conclusion: arithmetic on a void* is illegal in both C and C++.

GCC allows it as an extension, see Arithmetic on void- and Function-Pointers (note that this section is part of the "C Extensions" chapter of the manual). Clang and ICC likely allow void* arithmetic for the purposes of compatibility with GCC. Other compilers (such as MSVC) disallow arithmetic on void*, and GCC disallows it if the -pedantic-errors flag is specified, or if the -Werror-pointer-arith flag is specified (this flag is useful if your code base must also compile with MSVC).

The C Standard Speaks

Quotes are taken from the n1256 draft.

The standard's description of the addition operation states:

> 6.5.6-2: For addition, either both > operands shall have arithmetic type, > or one operand shall be a pointer to > an object type and the other shall > have integer type.

So, the question here is whether void* is a pointer to an "object type", or equivalently, whether void is an "object type". The definition for "object type" is:

> 6.2.5.1: Types are partitioned into object types (types that fully describe objects) , function types (types that describe functions), and incomplete types (types that describe objects but lack information needed to determine their sizes).

And the standard defines void as:

> 6.2.5-19: The void type comprises > an empty set of values; > it is an incomplete type that cannot > be completed.

Since void is an incomplete type, it is not an object type. Therefore it is not a valid operand to an addition operation.

Therefore you cannot perform pointer arithmetic on a void pointer.

Notes

Originally, it was thought that void* arithmetic was permitted, because of these sections of the C standard:

> 6.2.5-27: A pointer to void shall have the same representation and alignment > requirements as a pointer to a > character type.

However,

> The same representation and alignment > requirements are meant to imply > interchangeability as arguments to > functions, return values from > functions, and members of unions.

So this means that printf("%s", x) has the same meaning whether x has type char* or void*, but it does not mean that you can do arithmetic on a void*.

Solution 2 - C

Pointer arithmetic is not allowed on void* pointers.

Solution 3 - C

cast it to a char pointer an increment your pointer forward x bytes ahead.

Solution 4 - C

The C standard does not allow void pointer arithmetic. However, GNU C is allowed by considering the size of void is 1.

C11 standard §6.2.5

Paragraph - 19

> The void type comprises an empty set of values; it is an incomplete > object type that cannot be completed.

Following program is working fine in GCC compiler.

#include<stdio.h>

int main()
{
    int arr[2] = {1, 2};
    void *ptr = &arr;
    ptr = ptr + sizeof(int);
    printf("%d\n", *(int *)ptr);
    return 0;
}

May be other compilers generate an error.

Solution 5 - C

You can't do pointer arithmetic on void * types, for exactly this reason!

Solution 6 - C

Void pointers can point to any memory chunk. Hence the compiler does not know how many bytes to increment/decrement when we attempt pointer arithmetic on a void pointer. Therefore void pointers must be first typecast to a known type before they can be involved in any pointer arithmetic.

void *p = malloc(sizeof(char)*10);
p++; //compiler does how many where to pint the pointer after this increment operation

char * c = (char *)p;
c++;  // compiler will increment the c by 1, since size of char is 1 byte.

Solution 7 - C

You have to cast it to another type of pointer before doing pointer arithmetic.

Solution 8 - C

Pointer arithmetic is not allowed in the void pointer.

Reason: Pointer arithmetic is not the same as normal arithmetic, as it happens relative to the base address.

Solution: Use the type cast operator at the time of the arithmetic, this will make the base data type known for the expression doing the pointer arithmetic. ex: point is the void pointer

*point=*point +1; //Not valid
*(int *)point= *(int *)point +1; //valid

Solution 9 - C

Compiler knows by type cast. Given a void *x:

  • x+1 adds one byte to x, pointer goes to byte x+1
  • (int*)x+1 adds sizeof(int) bytes, pointer goes to byte x + sizeof(int)
  • (float*)x+1 addres sizeof(float) bytes, etc.

Althought the first item is not portable and is against the Galateo of C/C++, it is nevertheless C-language-correct, meaning it will compile to something on most compilers possibly necessitating an appropriate flag (like -Wpointer-arith)

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionSiva SankaranView Question on Stackoverflow
Solution 1 - CSadeqView Answer on Stackoverflow
Solution 2 - CmtvecView Answer on Stackoverflow
Solution 3 - CUltimate GobblementView Answer on Stackoverflow
Solution 4 - CmscView Answer on Stackoverflow
Solution 5 - COliver CharlesworthView Answer on Stackoverflow
Solution 6 - Cuser1581106View Answer on Stackoverflow
Solution 7 - CJakobView Answer on Stackoverflow
Solution 8 - CNeeraj SinghView Answer on Stackoverflow
Solution 9 - CrytisView Answer on Stackoverflow