When a pointer to a particular type (say int
, char
, float
, ..) is incremented, its value is increased by the size of that data type. If a void
pointer which points to data of size x
is incremented, how does it get to point x
bytes ahead? How does the compiler know to add x
to value of the pointer?

- 1
- 11
- 47
- 78

- 2,407
- 2
- 15
- 4
-
1possible duplicate of [Error Performing Pointer Arithmetic on void * in MSVC](http://stackoverflow.com/questions/3498850/error-performing-pointer-arithmetic-on-void-in-msvc) – Carl Norum Aug 19 '10 at 21:43
-
4The question sounds as though it assumes that the compiler(/run-time) knows what type of object the pointer was set to, and adds its size to the pointer. That is a complete misconception: it only knows the address. – PJTraill May 05 '15 at 21:22
-
3"If a `void` pointer which points to data of size `x` is incremented, how does it get to point `x` bytes ahead?" It doesn't. Why can't people who have such questions test them before asking - y'know, at least to the bare minimum where they check whether it actually compiles, which this doesn't. -1, can't believe this got +100 and -0. – underscore_d Aug 20 '16 at 06:30
-
@underscore_d because its a good question. We must know WHY it does not compile. It would be perfectly logical to assume that adding 1 to `void *` advances address by 1 byte (same as `char *`). Yet, the stupid illogical standard of it being "illegal" is forced upon everybody for no reason. – ScienceDiscoverer Jul 18 '22 at 14:16
-
@ScienceDiscoverer Yes, it is a good question. But the stupidity and illogicality are your opinion. In my opinion, it's perfectly logical that arithmetic on void pointers doesn't work, because in C, `p + n` obviously has to add `n * sizeof(*p)` to the address in `p`, but `sizeof(void)` is obviously 0. – Steve Summit Oct 08 '22 at 12:06
10 Answers
Final conclusion: arithmetic on a void*
is illegal in both C and C++.
GCC allows it as an extension, see Arithmetic on void
- and Function-Pointers (note that this section is part of the "C Extensions" chapter of the manual). Clang and ICC likely allow void*
arithmetic for the purposes of compatibility with GCC. Other compilers (such as MSVC) disallow arithmetic on void*
, and GCC disallows it if the -pedantic-errors
flag is specified, or if the -Werror=pointer-arith
flag is specified (this flag is useful if your code base must also compile with MSVC).
The C Standard Speaks
Quotes are taken from the n1256 draft.
The standard's description of the addition operation states:
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.
So, the question here is whether void*
is a pointer to an "object type", or equivalently, whether void
is an "object type". The definition for "object type" is:
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).
And the standard defines void
as:
6.2.5-19: The
void
type comprises an empty set of values; it is an incomplete type that cannot be completed.
Since void
is an incomplete type, it is not an object type. Therefore it is not a valid operand to an addition operation.
Therefore you cannot perform pointer arithmetic on a void
pointer.
Notes
Originally, it was thought that void*
arithmetic was permitted, because of these sections of the C standard:
6.2.5-27: A pointer to void shall have the same representation and alignment requirements as a pointer to a character type.
However,
The same representation and alignment requirements are meant to imply interchangeability as arguments to functions, return values from functions, and members of unions.
So this means that printf("%s", x)
has the same meaning whether x
has type char*
or void*
, but it does not mean that you can do arithmetic on a void*
.
-
10From 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. – mtvec Aug 19 '10 at 18:29
-
@Job: I answered to your reason. please check my answer in the asked question. – Sadeq Aug 19 '10 at 20:52
-
1
-
1This answer was useful even though it proved wrong as it contains conclusive proof that void pointers aren't meant for arithmetic. – Ben Flynn Oct 17 '12 at 21:48
-
1This is a good answer, it has the right conclusion and the necessary citations, but people who came to this question came to the wrong conclusion because they didn't read to the bottom of the answer. I've edited this to make it more obvious. – Dietrich Epp May 11 '13 at 02:37
-
I tried using `-Werror-pointer-arith` as a command line option for arm-xilinx-linux-gnueabi-g++, but it wasn't recognized. When was this flag added to gcc? Where can I find more info/a list of flags? – Moberg Dec 05 '13 at 14:46
-
Good flags to use on GCC|Clang: `{clang|gcc} -Wpedantic -Werror -Wall -ansi foo.c` – Dec 03 '14 at 10:02
-
@Barry: Yes, except please, please use `-std=c99` (or c11) instead of `-ansi`. `-ansi` makes GCC use the C89 standard, which is ancient, and has ugly limitations, such as requiring all variable declarations at the start of a block. Only use C89 if you have to... – sleske Feb 02 '15 at 09:15
-
@Barry: Well, I find several features of C99 quite valuable (position of var. declarations, new integer types, C++ comments), so I'd always use C99 unless there's a compelling reason for C89. Of course, if your compiler only supports C89, you'll have to use that. – sleske Feb 07 '15 at 12:08
-
Your last quote is from a footnote, which is non-normative. I think ``printf("%s", x)` is UB although a lot of the printf specification is badly written. – M.M Sep 25 '15 at 23:04
-
1Clang and ICC don't allow `void*` arithmetic (at least by default). – Sergey Podobry Jan 05 '16 at 18:14
-
I wonder why the C standard didn't assume the size of `void *` is a bit, that way pointer arithmetic on `void *` would be a bitwise operation. – Geremia Jan 30 '16 at 20:35
-
I think it's worrying that gcc will just issue a warning when using `Werror-pointer-arith` instead of downright failing to compile (as it should). – Martin May 11 '16 at 16:03
-
@Barry: Wrong. Engineering is precisely about developing new technology to make people's lives easier. Novelty isn't inherently superior, features that make developer's lives easier are. And C99 clearly has them over C89. – Martin May 11 '16 at 16:05
-
The C11 Standard actually differs on the definition of void: 6.2.5.19: "The void type comprises an empty set of values; it is an incomplete object type that cannot be completed." So in C11, void is an object type. I think this means pointer addition on void* pointers is now allowed. – Steve Siegel Dec 14 '16 at 01:46
-
3Oh, but for pointer addition, now "one operand shall be a pointer to a complete object type and the other shall have integer type.". So I guess pointer addition with a void* pointer is still undefined behavior. – Steve Siegel Dec 14 '16 at 01:55
-
@Geremia It already assumes that `void *` is same as `char *` in many contexts. it would be totally logical to assume `void *` to be of 1 byte size. Yet, standard somehow ended up being illogical and irrational. – ScienceDiscoverer Jul 18 '22 at 16:48
Pointer arithmetic is not allowed on void*
pointers.

- 17,846
- 5
- 52
- 83
-
19+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 Aug 19 '10 at 15:33
-
1@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) – mtvec Aug 19 '10 at 18:39
-
1Apparently it is not so with gcc 7.3.0. Compiler accepts p + 1024, where p is void*. And result is the same as ((char *)p) + 1024 – uuu777 Mar 24 '19 at 02:27
-
cast it to a char pointer an increment your pointer forward x bytes ahead.

- 1,851
- 16
- 23
-
14If you are writing your sort function, which according to `man 3 qsort` should have the `void qsort(void *base, size_t nmemb, size_t size, [snip])`, then you have no way of knowing the "right type" – alisianoi May 14 '17 at 15:30
-
Also, if you are writing something like the Linux kernel's container_of macro, then you need a way to compensate for different compilers' packing of structs. For example, given this struct: ... `typedef struct a_ { x X; y Y; } a;` ... If you then have a variable `y *B = (something)` and you want a pointer to B's enclosing `a` struct (presuming it exists), then you end up needing to do something like this: ... `a *A = (a*)(((char*)B) - offsetof(a, Y));` ... If you do this instead: ... `a *A = (a*)(((x*)B)-1);` ... then you may or may not get some very nasty surprises! – chadjoan Oct 08 '20 at 11:28
The C standard does not allow void pointer arithmetic. However, GNU C is allowed by considering the size of void is 1
.
C11 standard §6.2.5
Paragraph - 19
The
void
type comprises an empty set of values; it is an incomplete object type that cannot be completed.
Following program is working fine in GCC compiler.
#include<stdio.h>
int main()
{
int arr[2] = {1, 2};
void *ptr = &arr;
ptr = ptr + sizeof(int);
printf("%d\n", *(int *)ptr);
return 0;
}
May be other compilers generate an error.

- 33,420
- 29
- 119
- 214
You can't do pointer arithmetic on void *
types, for exactly this reason!

- 267,707
- 33
- 569
- 680
Void pointers can point to any memory chunk. Hence the compiler does not know how many bytes to increment/decrement when we attempt pointer arithmetic on a void pointer. Therefore void pointers must be first typecast to a known type before they can be involved in any pointer arithmetic.
void *p = malloc(sizeof(char)*10);
p++; //compiler does how many where to pint the pointer after this increment operation
char * c = (char *)p;
c++; // compiler will increment the c by 1, since size of char is 1 byte.

- 78,834
- 30
- 123
- 180
You have to cast it to another type of pointer before doing pointer arithmetic.

- 24,154
- 8
- 46
- 57
[answer copied from a comment on a later, duplicate question]
Allowing arithmetic on void pointers is a controversial, nonstandard extension. If you're thinking in assembly language, where pointers are just addresses, arithmetic on void pointers makes sense, and adding 1 just adds 1. But if you're thinking in C terms, using C's model of pointer arithmetic, adding 1 to any pointer p
actually adds sizeof(*p)
to the address, and this is what you want pointer arithmetic to do, but since sizeof(void)
is 0, it breaks down for void pointers.
If you're thinking in C terms you don't mind that it breaks down, and you don't mind inserting explicit casts to (char *)
if that's the arithmetic you want. But if you're thinking in assembler you want it to just work, which is why the extension (though a departure from the proper definition of pointer arithmetic in C) is desirable in some circles, and provided by some compilers.

- 45,437
- 7
- 70
- 103
Pointer arithmetic is not allowed in the void pointer.
Reason: Pointer arithmetic is not the same as normal arithmetic, as it happens relative to the base address.
Solution: Use the type cast operator at the time of the arithmetic, this will make the base data type known for the expression doing the pointer arithmetic. ex: point is the void pointer
*point=*point +1; //Not valid
*(int *)point= *(int *)point +1; //valid

- 149
- 2
- 3
Compiler knows by type cast. Given a void *x
:
x+1
adds one byte tox
, pointer goes to bytex+1
(int*)x+1
addssizeof(int)
bytes, pointer goes to bytex + sizeof(int)
(float*)x+1
addressizeof(float)
bytes, etc.
Althought the first item is not portable and is against the Galateo of C/C++, it is nevertheless C-language-correct, meaning it will compile to something on most compilers possibly necessitating an appropriate flag (like -Wpointer-arith)

- 648
- 5
- 10
-
2`Althought the first item is not portable and is against the Galateo of C/C++` True. `it is nevertheless C-language-correct` False. This is doublethink! Pointer arithmetic on `void *` is syntactically illegal, should not compile, and produces undefined behaviour if it does. If a careless programmer can make it compile by disabling some warning, that's no excuse. – underscore_d Aug 20 '16 at 06:35
-
1@underscore_d: I think some compilers used to allow it as an extension, since it's a lot more convenient than having to cast to `unsigned char*` to e.g. add a `sizeof` value to a pointer. – supercat Aug 23 '16 at 14:42