this is my C code:
int main()
{
void * ptr_void;
void ** ptr_2void;
ptr_void = ptr_2void;
return 0;
}
i am just wondering why this code is valid? i have assigned an (void *)
to (void **)
, the compiler pass it even without a warning. the type looks mismatch. and the following code that assigning an (void **)
to (int *)
also works.
int main()
{
int * ptr_int;
void ** ptr_2void;
ptr_int = ptr_2void;
return 0;
}
anyone is able to figure out what is exactly of (void *)
stuff?
void pointers are type converted to pointers to any other data type implicitly. The compiler will not show any warning. Similarly type converting from pointer of any type to void *
will also work without a warning.
Other than for void pointers, if you try to convert from one pointer type to another pointer type implicitly a warning will be issued by the compiler.
For example consider the code given below, It will give you the warning " assignment from incompatible pointer type
".
int *intptr;
void *voidptr;
void **vvptr;
int intval=123;
voidptr=&intval;
vvptr=voidptr;
intptr=vvptr;
The line of code causing the warning is intptr=vvptr;
because intptr
is an integer pointer
and vvptr
is a pointer of type void **
. None of them are void *
pointers and thus a warning.
In order to avoid this warning, you have to explicitly type cast the void **
type to int *
type. If you change the line intptr=vvptr;
to intptr=(int *)vvptr;
then the warning will not be shown by the compiler.
It's important to distinguish between a conversion and a cast .
A conversion transforms a value of one type to a value of another type. A cast is an operator (consisting of a type name in parentheses) that explicitly specifies a conversion. A conversion may be either explicit (specified by a cast operator) or implicit. Most pointer conversions require a cast operator; pointer conversions involving void*
are the exception to this.
A value of any pointer-to-object type (or pointer-to-incomplete type) may be converted to void*
and back to its original type; the resulting pointer is guaranteed to compare equal to the original pointer.
In an assignment (or when passing an argument to a function, or in a return
statement), a conversion to or from void*
may be done implicitly, with no cast operator.
In your first code sample:
void * ptr_void;
void ** ptr_2void;
ptr_void = ptr_2void;
the assignment is permitted because a void**
may be converted to a void*
without a cast. There's nothing special about void**
here; a pointer to anything may be converted to a void*
without a cast. ( void*
is a generic pointer type; void**
is not a generic pointer-to-pointer type, and in fact there is no generic pointer-to-pointer type.)
In your second code sample:
int * ptr_int;
void ** ptr_2void;
ptr_int = ptr_2void;
the assignment is not valid; it's a constraint violation . There is no implicit conversion between int*
and void**
, since neither type is void*
. Any conforming C compiler must issue a diagnostic message for the assignment. In some cases, the diagnostic may be a warning, and the compiler will probably generate an implicit conversion as if you had written a cast. In other cases, a compiler may require additional options to cause it to diagnose this violation.
Note that the above does not apply to function pointers. Any function pointer type may be converted (with a cast) to any other function pointer type, converting a function pointer to void*
or vice versa has undefined behavior (though it may be supported by some compilers).
void**
and void*
are different types. int*
and void**
are different types too. But as Barmar says, any data pointer type can be cast to/from void*.
That means you can cast int*
to void*
, but you cannot cast int*
to void**
, as void**
does not have this same special property.
gcc
should give a warning:
warning: assignment from incompatible pointer type [enabled by default]
ptr_int = ptr_2void;
See this question: Passing to void** instead void* makes the compiler complain about types, why?
void * is a type that is implicitly convertible to and from any object pointer type. void ** isn't - so while you can assign a char * to a void *, you can not do the same with char ** and void **.
The reason is that they are incompatible types: char ** points to a char *, void ** points to a void *, so their base types don't match.
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.