Search code examples
cvisual-studiogccvoid-pointerspointer-arithmetic

Pointer arithmetic when void has unknown size


In Visual Studio C++ version 9 (and probably other versions too), the following code:

int a = sizeof(void);
void const *b = static_cast<void const *>("hello world");
b += 6;

Generates these errors:

error C2070: 'void': illegal sizeof operand
error C2036: 'const void *' : unknown size

This code works under GCC, which treats sizeof(void) as 1.

Is there some way around this limitation, as casting explicitly to char * for purposes of pointer arithmetic adds to the confusion (void * is well recognised and used as a typeless pointer to raw memory).

Update0

  • Please note, I'm well aware of the existence of the standard.
  • I want to do raw pointer arithmetic.
  • I take sizeof(void) to show that I'm well aware the fact that it isn't 1 is the cause of the problem.
  • The code example is simply to demonstrate what is required to generate the errors.
  • I know this isn't a "normal" way to use void, but this is C, and these things happen.
  • Yes, people need to do this at low-level. I'm not after why, I'm after how. If you want to know why, take a look at some kernel source, or your friendly glibc.

Update1

It seems this question has generated a great deal of confusion. The question is not about why having sizeof(void) == 1 is not standard, but what to do when it isn't.

In the instance that single-byte pointer arithmetic is to be done, it turns out that casting to char * is the correct answer, not because *(void *) has no size, but because the standard actually guarantees that *(char *) is always 1. Therefore the use of char * is always correct, and congruent with void * with the GCC extension for the purposes of raw pointer arithmetic.

To further reinforce the point, void * is the correct choice for pointers to typeless memory, and char * is the correct type to cast to for raw pointer arithmetic.


Solution

  • It would appear the correct answer is to use char * for pointer arithmetic, because sizeof(char) is always defined to be 1, and to be of the finest addressable granularity on any platform.

    So in short, there is no way around the limitation, char * is in fact the proper way to do it.

    Matthias Wandel had the right answer but with a different justification.