Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I do arithmetic on void * pointers in C?

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

Summary:

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
like image 619
pm100 Avatar asked Oct 25 '10 23:10

pm100


People also ask

Can we do arithmetic operations on pointers?

You can perform a limited number of arithmetic operations on pointers. These operations are: Increment and decrement. Addition and subtraction.

Can pointers be void?

The void pointer in C is a pointer that is not associated with any data types. It points to some data location in the storage. This means that it points to the address of variables. It is also called the general purpose pointer.

Can you free a void * in C?

Not only is it OK to free() a void * value, by definition, all free() ever sees is a void * , so technically, everything freed in C is void * :-) @Daniel - If you ask me, it should be struct foo *p = malloc(sizeof *p)); but what do I know?

Can void pointers point to anything?

A void pointer is a pointer that can point to any type of object, but does not know what type of object it points to. A void pointer must be explicitly cast into another type of pointer to perform indirection. A null pointer is a pointer that does not point to an address. A void pointer can be a null pointer.


1 Answers

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.

EDIT

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
like image 100
JaredPar Avatar answered Oct 19 '22 15:10

JaredPar