简体   繁体   中英

void* vs. char* pointer arithmetic

I'm looking through my textbook and I'm a little confused about some of the code that is in there. In one part, they are performing pointer arithmetic in the following way:

void* bp;
...
bp = (void*)((char*)(bp)+16);
...

but later on, they do the following:

void* bp;
...
bp = bp+16;
...

I feel like they should be two different things but they are treating it like the same thing. I feel this way because, for example, if you were to do an array access (for an integer array for example),you would do the following

int* a = malloc(n*sizeof(int));
...
q = *(a+1);
...

in this case, aren't I accessing the next 4 bytes in the integer array and not the next byte? Similarly, I feel that if I have void* a, then *(a+1) should be the next 4 bytes... Or is that not the case? Thank you.

It's a slip-up. Arithmetic on void * is not defined by the standard, but some compilers offer it as an extension, behaving the same as char * for arithmetic. The second is formally not valid C, but slipped through presumably out of (bad) habit.

The accepted answer is a good summary and I want to make it more clear why to use one or another. ;)

Although (void *) and (char *) can be both equivalently cast to any other pointer type, it is only legal to perform pointer arithmetic on a (char *) and not with (void *) if you want to comply with Standard C.

Why both are used as pointers? Most pointer conversions to and from (void *) can be done without a cast but the use of (char *) is a reminiscence of the old times.

GCC does not warn about pointer arithmetic on (void *) as it is not a compiler intended to be compliant with standard C but for GNU C. To behave in compliance with standard C you can use the following flags:

gcc -ansi -pedantic -Wall -Wextra -Werror <more args...>

My bottom line:

  • If you want to perform pointer arithmetic: use (char *)
  • If you want to get the pointer address in order to cast it into another type later on: use (void *)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM