views:

227

answers:

6

If a particular type(say int,char,float,..) pointer is incremented the value of pointer variable increased by number which is equal to size of the particular data type.If a void pointer points to data of x size for increment operation how it will point to x size ahead? How compiler knows to add x to value of the pointer?

+10  A: 

Pointer arithmetic is not allowed on void* pointers.

Job
+1 Pointer arithmetic is only defined for pointers to (complete) *object types*. `void` is an *incomplete type* that can never be completed by definition.
schot
@schot: Exactly. Moreover, pointer arithmetic is only defined on a pointer to an element of an array object and only if the result of the operation would be a pointer to an element in that same array or one past the last element of that array. If those conditions are not met, it is undefined behavior. (From C99 standard 6.5.6.8)
Job
+3  A: 

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

Oli Charlesworth
+1  A: 

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

DrDipshit
+1  A: 

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

Jakob
+1  A: 
supercat
+4  A: 

incrementing/decrementing a void* pointer, is a valid expression in C (but not in C++).

In the C standard (N1256 draft):

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

Edit: Also the C standard says:

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

Therefore incrementing/decrementing a void* pointer is equivalent to the char* pointer and some compilers (like GCC) support it (but it's not safe). e.g:

#include <stdio.h>

int main(int argc, char** argv)
{
    char c_str[5] = "abcd";
    void* zzz = c_str;

    printf("%s\n", (char*)zzz);
    zzz = zzz + 1;
    printf("%s\n", (char*)zzz);
    zzz = zzz + 1;
    printf("%s\n", (char*)zzz);
    zzz = zzz + 1;
    printf("%s\n", (char*)zzz);
    return 0;
}

According to the comments, the standard has defined void as an incomplete type:

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

And the standard has said this rule for additive operators:

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.

But the standard has never said this one instead of the above rule:

... or one operand shall be a pointer to a complete object type ....

The standard has never indicated that object type shall be a complete or an incomplete type, but it shall be "a pointer to an object type", and the standard has defined void as a type, thus void* is a pointer to a void type and 6.5.6-2 has never maked it clear that additive operator for void* is forbidden.

void is an incomplete type means that we can't access to its value/members.


OK, in the standard we can see this:

6.2.5.1: ... object types (types that fully describe objects) ...

Then it was my fault, now everyone can down vote my answer. ;-)

PC2st
From the C99 standard: (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.* (6.2.5.19) *The void type comprises an empty set of values; it is an incomplete type that cannot be completed.* I think that makes it clear that `void*` pointer arithmetic is not allowed. GCC has an [extension](http://gcc.gnu.org/onlinedocs/gcc-4.5.0/gcc/Pointer-Arith.html#Pointer-Arith) that allows to do this.
Job
@Job: I answered to your reason. please check my answer in the asked question.
PC2st
@PC2st: if you no longer think your answer is useful, you can just delete it.
caf