Take the 2-minute tour ×

is this valid

void *p = &X; /* some thing */
p += 12;

and if so what does p now point to? I have (third party) code that does this (and compiles cleanly) and my guess is that the void * was treated as a char *. My trusty K&R is silent(ish) on the topic

EDIT: My little test app runs fine on gcc 4.1.1 and treats void * as char *. But g++ barfs

I know how to do it properly. I need to know if I have to clean this code base to find all the places its done.

BTW gcc -pedantic throws up a warning


The C spec is ambiguous. It says that in terms of representation and use as function parameters void* =char*. But it is silent regarding pointer arithmetic.

  • gcc (4) permits it and treats it as char *
  • g++ refuses it
  • gcc -pedantic warns about it
  • vs2010 both c and c++ refuses it
share|improve this question
related? stackoverflow.com/questions/1997751/… –  pmg Oct 25 '10 at 23:54
add comment

7 Answers

up vote 0 down vote accepted

It depends on compiler. Those that allow it consider sizeof(*(void *)) as 1.

EDIT: it's only for void pointer arithmetic. It would have no sense using in this case steps of sizeof(int) or of 0. The common expectations of someone who uses it would be the smallest possible step.

share|improve this answer
What compiler allows for this? That implies that sizeof(void) == 1 which is ... not sane. –  JaredPar Oct 25 '10 at 23:44
Perhaps for small values of 1. –  Jason Whitehorn Oct 25 '10 at 23:48
@Jason, thank you for wasting a few minutes of my day as I sat in my chair helplessly laughing :) –  JaredPar Oct 25 '10 at 23:53
add comment

No this is not legal. A void* cannot be arbitrarily incremented. It needs to be cast to a specific type first.

If you want to increment it by a specific number of bytes then this is the solution I use.

p = ((char*)p) + 12;

The char type is convenient because it has a defined size of 1 byte.


It's interesting that it runs on gcc with a warning. I tested on Visual Studio 2010 and verified it does not compile. My limited understanding of the standard would say that gcc in the error here. Can you add the following compilation flags

-Wall -ansi -pedantic
share|improve this answer
Visual Studio compiles code as C++ by default, which is why it throws an error. –  casablanca Oct 25 '10 at 23:55
-pedantic throws a warning. compiling as c++ fatals it –  pm100 Oct 25 '10 at 23:56
@casablanca I'm still mystified as to how incrementing void* could be legal in C at all. It certainly doesn't seem portable. –  JaredPar Oct 25 '10 at 23:57
@JaredPar: I am as surprised as you are, and still waiting for a definitive answer on this. –  casablanca Oct 25 '10 at 23:58
@JaredPar: no, I don't think so. I haven't actually checked the text for the increment operator, but certainly the text for the addition operator talks only about pointers to object types, whereas void is an incomplete type. So ((void*)p) + 12; is a breach of language constraints (invalid program). MSVC is therefore correct to reject it, and GCC is correct to give it implementation-defined semantics and compile it with a warning. –  Steve Jessop Oct 27 '10 at 9:53
show 2 more comments

To quote from the spec:

§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. (Incrementing is equivalent to adding 1.)

A pointer to void is not a pointer to an object type, as per these excerpts:

§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).

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

Therefore, pointer arithmetic is not defined for pointer to void types.

share|improve this answer
+1 for pointing out that the C spec is not ambiguous on this. I would add that since 6.5.6/2 is part of a "Constraints" section, this is not undefined behavior, but rather a conforming compiler is required to issue a diagnostic ( In the case of gcc -pedantic, only a warning, but a diagnostic nonetheless. –  Steve Jessop Oct 26 '10 at 2:27
add comment

Your guess is correct.

In the standard ISO C99, section 6.2.5 paragraph 26, it declares that void pointers and character pointers will have the same representation and alignment requirements (paraphrasing).

share|improve this answer
It also says in §6.5.6 paragraph 2 that either both operands have arithmetic types or one operand has integer type and the other operand is a pointer to an object type (a pointer to void is not a pointer to an object type). So, arithmetic on a pointer to void is not defined. –  dreamlax Oct 26 '10 at 0:21
@dreamlax: And not defined means the compiler can do whatever the hell it wants to, including use an element size of 1. –  Ben Voigt Oct 26 '10 at 0:27
@dreamlax Yes, agreed. I misunderstood footnote 39. In para 1 it says that void * can be converted to/from anything with impunity. Given that it is required to have the same characteristics as char * it seems logical that it would be implicitly converted to a char * by the compiler. That said I think it is really bad practice to manipulate void * in this way. –  Marc Butler Oct 26 '10 at 0:47
@BenL "not defined" does mean that, but this isn't undefined behaviour, it's a breach of language constraints (the motivation is that the restriction is on the types of the operands, not their values; we know it to be a constraint because of the big heading "Constraints" immediately preceding it ;-)). Constraint violation must result in a diagnostic. Which, with -pedantic, it does, so no harm. GCC without -pedantic is not, and does not claim to be, a standard-confirming C compiler anyway. –  Steve Jessop Oct 26 '10 at 2:25
add comment

I don't think you can, because it doesn't know its type, therefore can not seek the correct amount of bytes.

Cast it to a type first, i.e. (int).

share|improve this answer
If you cast to int though then the += 12 is essentially interpreted as += sizeof(int)*12 in terms of how many bytes were actually added. This does not seem like the intended behavior. –  JaredPar Oct 25 '10 at 23:51
@JaredPar Would it work if that pointer did point to an integer though? –  alex Oct 25 '10 at 23:57
again depends on intent. If the intent was to move it 12 elements forward then yes. If the intent was to move it 12 bytes forward then no. Hard to read the intent from the question but my assumption is that the OP wants no increment 12 bytes. –  JaredPar Oct 25 '10 at 23:59
Usually it makes sense to cast (void *) to another pointer type, so for instance to (int *) or (char *) or (struct Foo *), or to some implementation dependent integer type, such as (size_t), even though in the latter case the resulting behavior is not standardized in any way. –  damix911 Jan 4 '13 at 18:17
add comment

i'm not sure this is valid...gcc seems to treat it as char but i don't know that it has to.

share|improve this answer
This is really a comment, not an answer to the question. Please use "add comment" to leave feedback for the author. –  Rostyslav Dzinko Aug 19 '12 at 13:32
add comment

You may want to have a look at the top voted answer to this question

Pointer arithmetic for void pointer in C

share|improve this answer
add comment

Your Answer


