Void ** a generic pointer?
void *
is a generic pointer, but what about void **
? Is void **
also a generic pointer?
Can we typecast void **
to int **
, char **
and so on.
I would be thankful to stack overflow family for any information on this.
No. void**
is a pointer to void*
, and nothing else. Only void*
acts like a generic pointer.
Note that actually trying it will probably yield consistent results, but only the above is mandated by the Standard, anything else is Undefined Behaviour and may crash without mercy.
void**
is a pointer to void*
. On top of it being undefined behavior (which while scary, the behavior is often in effect defined by your compiler), it is also a huge problem if you do the reinterpret_cast
:
int x = 3;
char c = 2;
int* y = &x;
void* c_v = &c; // perfectly safe and well defined
void** z = reinterpret_cast<void**>(&y); // danger danger will robinson
*z = c_v; // note, no cast on this line
*y = 2; // undefined behavior, probably trashes the stack
Pointers to pointers are very different beasts than pointers. Type changes that are relatively safe on pointers are not safe on pointers to pointers.
Void ** a generic pointer?
void **
is not a generic pointer. Standard says only about void *
to be a generic pointer.
Chapter 22: Pointers to Pointers:
One side point about pointers to pointers and memory allocation: although the
void *
type, as returned bymalloc
, is a generic pointer, suitable for assigning to or from pointers of any type, the hypothetical typevoid **
is not a generic pointer to pointer.
Can we typecast
void **
toint **
,char **
and so on.
No. You should not.
C-FAQ says that:
There is no generic pointer-to-pointer type in C.
void *
acts as a generic pointer only because conversions (if necessary) are applied automatically when other pointer types are assigned to and fromvoid *
's; these conversions cannot be performed if an attempt is made to indirect upon avoid **
value which points at a pointer type other thanvoid *
. When you make use of avoid **
pointer value (for instance, when you use the*
operator to access thevoid *
value to which thevoid **
points), the compiler has no way of knowing whether thatvoid *
value was once converted from some other pointer type. It must assume that it is nothing more than avoid *
; it cannot perform any implicit conversions.In other words, any
void **
value you play with must be the address of an actualvoid *
value somewhere; casts like(void **)&dp
, though they may shut the compiler up, are nonportable (and may not even do what you want; see also question 13.9). If the pointer that thevoid **
points to is not avoid *
, and if it has a different size or representation than avoid *
, then the compiler isn't going to be able to access it correctly.
C implementations are free to extend the language in such a way as to allow void**
to be used as a generic pointer-to-anything type in the presence of suitable casting operators, and in the days before the Standard implementations that could practically do so often did. The Standard does not mandate such treatment because there are some platforms that could not efficiently accommodate such usage. Presumably, the authors judged that requiring that programmers who need to make their code work on such platforms jump through hoops to work around the lack of a "pointer to any data pointer" type would be less harmful than requiring that implementations jump through hoops to accommodate such constructs without regard for whether their customers would use them. Such judgment does not imply that the authors of the Standard intended to require that programmers jump through such hoops even when writing code that would never be called upon to run on such platforms. Clang and gcc can be configured to support such constructs via the -fno-strict-aliasing
option.