19

Note: I'm a experienced C++ programmer, so I don't need any pointer basics. It's just that I never worked with void** and have kind of a hard time getting my mental model adjusted to void* vs. void**. I am hoping someone can explain this in a good way, so that I can remember the semantics more easily.

Consider the following code: (compiles with e.g. VC++ 2005)

int main() {
  int obj = 42;
  void* ptr_to_obj = &obj;
  void* addr_of_ptr_to_obj = &ptr_to_obj;
  void** ptr_to_ptr_to_obj = &ptr_to_obj;
  void* another_addr = ptr_to_ptr_to_obj[0];
  // another_addr+1; // not allowed : 'void*' unknown size
  ptr_to_ptr_to_obj+1; // allowed
}
Martin Ba
  • 37,187
  • 33
  • 183
  • 337
  • Your code compiles just fine with gcc 4.5.2, even the `another_addr+1;` part. Could you please add the error message you are getting? – Philip Apr 08 '11 at 08:56
  • 1
    @Philip: I recently stumbled over a posting that there is a GCC extension that allows to do arithmetic on void*. That's the reason why you do not get an error with GCC. The error message is already in the comment: 'void*' unknown size – Martin Ba Apr 08 '11 at 09:04
  • thanks for clarification. Man do I hate those GNU folks... – Philip Apr 08 '11 at 09:07

5 Answers5

33

void* is a pointer to something, but you don't know what. Because you don't know what it is, you don't know how much room it takes up, so you can't increment the pointer.

void** is a pointer to void*, so it's a pointer to a pointer. We know how much room pointers take up, so we can increment the void** pointer to point to the next pointer.

Simon Nickerson
  • 42,159
  • 20
  • 102
  • 127
7

A void* points to an object whose type is unknown to the compiler.

A void** points to a variable which stores such a void*.

fredoverflow
  • 256,549
  • 94
  • 388
  • 662
4

A void * can point at anything (except functions). So it can even point at pointers, so it can even point at other void * objects.

A void ** is a pointer-to-void *, so it can only be used to point at void * objects.

Oliver Charlesworth
  • 267,707
  • 33
  • 569
  • 680
1

void is misleading because it sounds like null. However, it's better to think of void as an unspecified type. So a void* is pointer for an unspecified type, and a void** is a pointer to a pointer for an unspecified type.

ctford
  • 7,189
  • 4
  • 34
  • 51
  • "However, it's better to think of void as an unspecified type." great explanation in the context of `void*`, but should be explicitly qualified for that context as that's totally wrong for return types, argument lists etc.. – Tony Delroy Apr 08 '11 at 08:20
1

void is a type which has no objects.

void * is a conventional scalar type.

void ** is also a conventional scalar type that happens to point to void *.


void * can be used to point to anything, but I prefer to use it only for uninitialized storage. There is usually a better alternative to pointing a void * at an actual object.

Potatoswatter
  • 134,909
  • 25
  • 265
  • 421