58

I have a void pointer called ptr. I want to increment this value by a number of bytes. Is there a way to do this?

Please note that I want to do this in-place without creating any more variables.

Could I do something like ptr = (void *)(++((char *) ptr)); ?

Adam S
  • 8,945
  • 17
  • 67
  • 103

5 Answers5

92

You cannot perform arithmetic on a void pointer because pointer arithmetic is defined in terms of the size of the pointed-to object.

You can, however, cast the pointer to a char*, do arithmetic on that pointer, and then convert it back to a void*:

void* p = /* get a pointer somehow */;

// In C++:
p = static_cast<char*>(p) + 1;

// In C:
p = (char*)p + 1;
James McNellis
  • 348,265
  • 75
  • 913
  • 977
28

No arithmeatic operations can be done on void pointer.

The compiler doesn't know the size of the item(s) the void pointer is pointing to. You can cast the pointer to (char *) to do so.

In gcc there is an extension which treats the size of a void as 1. so one can use arithematic on a void* to add an offset in bytes, but using it would yield non-portable code.

Alok Save
  • 202,538
  • 53
  • 430
  • 533
  • 3
    In GCC it's possible because `sizeof(void)` yields `1`. – Blagovest Buyukliev Jun 23 '11 at 06:09
  • 2
    @Blagovest Buyukliev: It is extension in GCC which treats the size of a void as 1, Using it would yield non-portable code. – Alok Save Jun 23 '11 at 06:11
  • 6
    @Blag: As always, please compile with `-pedantic`. :) – Xeo Jun 23 '11 at 06:13
  • With `-Wpedantic`, as suggested by @Xeo, I got a new `warning: pointer of type ‘void *’ used in arithmetic [-Wpointer-arith]`. Solved by casting (to `uint8_t` in my case which I'm using for bytes). – Daniel Sep 15 '22 at 14:08
8

Just incrementing the void* does happen to work in gcc:

#include <stdlib.h>
#include <stdio.h>

int main() {
    int i[] = { 23, 42 };
    void* a = &i;
    void* b = a + 4;
    printf("%i\n", *((int*)b));
    return 0;
}

It's conceptually (and officially) wrong though, so you want to make it explicit: cast it to char* and then back.

void* a = get_me_a_pointer();
void* b = (void*)((char*)a + some_number);

This makes it obvious that you're increasing by a number of bytes.

tdammers
  • 20,353
  • 1
  • 39
  • 56
  • 1
    As always, please compile with `-pedantic`. :) It's a non-conforming extension by GCC. – Xeo Jun 23 '11 at 06:13
2

You can do:

++(*((char **)(&ptr)));
EyalSh
  • 39
  • 3
  • 11
    Yeah, but why _would_ you? That's horrible obscure code that makes it needlessly difficult to parse what it's doing, for no good reason. Also, C-style casts are to be discouraged in C++, but that's the least of the problems here. – underscore_d May 23 '17 at 10:14
  • 10
    You can also shove a flaming stick into your eye. It would probably hurt less than looking at `++(*((char **)(&ptr)));`. – Andrew Henle May 23 '17 at 10:27
  • 2
    He wanted to do this in-place without creating any more variables, so I gave this solution. You can see it as an instructional way, but definitely not for using it in your code. – EyalSh Jan 22 '19 at 17:56
0

Logically, arithmetic on void pointers should not be allowed at all as the size of the data type is not available.

But some compilers like the GCC assume void to be of size 1 byte and a increment on a void pointer x will be equivalent to x + 1.

To confirm this, I wrote a small program which is as follows

#include<bits/stdc++.h>
using namespace std;

int main(){
  int x = 10;
  void* y = (void*) &x;
  cout<<y<<endl;
  void *z = y;
  z++;
  cout<<(z)<<endl;
  cout<<(y+1)<<endl;
}

And the output is as follows You can

But GCC does give warnings while compiling enter image description here

Sai Teja
  • 11
  • 4