#include <stdio.h>
void fun1(int *c){return;}
void fun2(void *p){return;}
void fun3(void **p){return;}
typedef void (* myfunptr)(void *);
void fun4(myfunptr b){
return;
}
int
main(){
int *p;
void *q = p;
fun1(p); //no warning
fun1(q); //no warning
fun2(p); //no warning
fun2(q); //no warning
fun3(&p); //warning - incompatible pointer types
fun3(&q); //no warning
fun4(fun1); //warning - incompatible pointer types
fun4(fun2); //no warning
return 0;
}
I am realizing warning at fun3(&p)
as void **
is not a generic pointer like void *
. However, I'm a little puzzled why there is a warning in the case of fun4(fun1)
, as void *
and int *
are implicitly converted without warning.
My next question is there a way I will get warnings of "incompatible types" for all non-compatible pointer conversion except when void *
or void **
involved. Because using -Wno-incompatible-pointer-types
disables warnings of all types of conversions.
fun1(p); //no warning
int*
is obviously compatible with int*
fun1(q); //no warning
void*
, as a special case type, is compatible with every other object pointer type and are implicitly converted to/from other pointers to object type.
fun2(p); //no warning
As already mentioned, void*
and int*
can be implicitly converted to/from each other.
fun2(q); //no warning
void*
is obviously compatible with void*
fun3(&p); //warning - incompatible pointer types
The special rule for void*
does not apply "recursively". void**
is not a generic object pointer type. It is not compatible with int**
. You'll see some trashy APIs doing such conversions still (CUDA etc), but they are bad and relying on non-standard behavior.
fun3(&q); //no warning
void**
is obviously compatible with void**
.
fun4(fun1); //warning - incompatible pointer types
Function pointers need to point at identical functions to be compatible. Same return type, same parameters, same qualifiers.
fun4(fun2); //no warning
You provide a function pointer of the expected type, so it is fine. Please note that fun2
in this case "decays" from a function to a function pointer, since it is used in an expression.
Also please note that void*
is the generic object pointer. You cannot use it as a generic pointer type to mix with function pointers!