问题
Assuming this program:
#include <stdio.h>
#include <string.h>
static void ring_pool_alloc(void **p, size_t n) {
static unsigned char pool[256], i = 0;
*p = &pool[i];
i += n;
}
int main(void) {
char *str;
ring_pool_alloc(&str, 7);
strcpy(str, "foobar");
printf("%s\n", str);
return 0;
}
... is it possible to somehow avoid the GCC warning
test.c:12: warning: passing argument 1 of ‘ring_pool_alloc’ from incompatible pointer type
test.c:4: note: expected ‘void **’ but argument is of type ‘char **’
... without casting to (void**) (or simply disabling the compatibility checks)? Because I would very much like to keep compatibility warnings regarding indirection-level...
回答1:
Why don’t you change the method signature such that it returns the new pointer instead of passing it by pointer? In fact, just like regular malloc
does:
static void * ring_pool_alloc(size_t n) {
static unsigned char pool[256], i = 0;
void *p = &pool[i];
i += n;
return p;
}
int main(void) {
char *str = ring_pool_alloc(7);
strcpy(str, "foobar");
printf("%s\n", str);
return 0;
}
回答2:
Change ring_pool_alloc
to receive a void *
. You can then recast to void **
in the function, if you wish.
Or in your specific case:
/* You can pass any pointer as a first parameter */
static void ring_pool_alloc(void *r, size_t n) {
unsigned char **p = r; /* no cast necessary */
static unsigned char pool[256], i = 0;
*p = &pool[i];
i += n;
}
Note that void **
cannot act as a generic pointer-to-pointer type. On the other hand, convertions from and to void *
with other pointer types are applied automatically.
回答3:
Simply change:
static void ring_pool_alloc(void **p, size_t n) {
to:
static void ring_pool_alloc(char **p, size_t n) {
来源:https://stackoverflow.com/questions/2943983/avoid-incompatible-pointer-warning-when-dealing-with-double-indirection