Разве gcc не должен выдавать предупреждение о типе, потому что void*
передается в void**
параметр функции?
Я пробовал clang, gcc4.8 и gcc9. Никто из них, кажется, не заботится:
gcc -Wall -c t.c
void f(void *a)
{
}
void g(void **b)
{
f(b);
}
t.c: In function ‘g’:
t.c:7:2: warning: passing argument 1 of ‘f’ from incompatible pointer type [enabled by default]
f(&b);
^
t.c:1:6: note: expected ‘void **’ but argument is of type ‘char *’
void f(void **a)
void f(void **a)
{
}
void g(char b)
{
f(&b);
}
t.c: In function ‘g’:
t.c:7:2: warning: passing argument 1 of ‘f’ from incompatible pointer type [enabled by default]
f(&b);
^
t.c:1:6: note: expected ‘void **’ but argument is of type ‘char **’
void f(void **a)
void f(void **a)
{
}
void g(char *b)
{
f(&b);
}
void f(void *a)
{
}
void g(char b)
{
f(&b);
}
поэтому иногда он заботится о том, чтобы тип указателя передавался в void**
, а иногда нет. Таким образом, void*
и void**
не всегда рассматриваются одинаково. Также char**
не будет транслироваться на void**
.
Тип void *
получает особое внимание. В основном это означает указатель на какой-то неизвестный тип. Указатель объекта Любой может быть преобразован в или из void *
без приведения.
@Zakk Вовсе нет. void **
— это указатель на определенный тип, а именно на void *
. void *
может указывать на что угодно.
@Zakk, Только в том же смысле, что struct Foo*
и void *
эквивалентны: вы можете преобразовать их без явного приведения. Но на этом эквивалентность заканчивается. Они могут быть даже не одного размера!
@dbush Итак, f(b)
должно было быть f(*b)
, не так ли?
@Zakk Зависит от того, что f
собирается делать с этим параметром. В этом случае функция имеет пустое тело, так что это не имеет большого значения. Найдите функцию qsort
, чтобы увидеть пример использования функции с параметром void *
.
@Zakk, это правда. Я пропустил это, когда писал код, и был удивлен, что компилятор не предупредил меня, отсюда и этот вопрос. В моем случае это код выделения памяти.
dbush, смотрите обновление в вопросе. Интересно насчет char** и void**.
@ KJ7LNW Как я уже сказал, к void *
относятся по-особому. void **
нет.
Вы имеете в виду, что
void*
иvoid**
эквивалентны?