Почему GCC не выдает ошибок при передаче параметра void * в параметр void**?

Разве 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**.

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
0
34
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Тип void * получает особое внимание. В основном это означает указатель на какой-то неизвестный тип. Указатель объекта Любой может быть преобразован в или из void * без приведения.

Вы имеете в виду, что void* и void** эквивалентны?

Zakk 19.03.2022 20:49

@Zakk Вовсе нет. void ** — это указатель на определенный тип, а именно на void *. void * может указывать на что угодно.

dbush 19.03.2022 20:50

@Zakk, Только в том же смысле, что struct Foo* и void * эквивалентны: вы можете преобразовать их без явного приведения. Но на этом эквивалентность заканчивается. Они могут быть даже не одного размера!

ikegami 19.03.2022 20:51

@dbush Итак, f(b) должно было быть f(*b), не так ли?

Zakk 19.03.2022 20:58

@Zakk Зависит от того, что f собирается делать с этим параметром. В этом случае функция имеет пустое тело, так что это не имеет большого значения. Найдите функцию qsort, чтобы увидеть пример использования функции с параметром void *.

dbush 19.03.2022 21:00

@Zakk, это правда. Я пропустил это, когда писал код, и был удивлен, что компилятор не предупредил меня, отсюда и этот вопрос. В моем случае это код выделения памяти.

KJ7LNW 19.03.2022 21:01

dbush, смотрите обновление в вопросе. Интересно насчет char** и void**.

KJ7LNW 19.03.2022 21:14

@ KJ7LNW Как я уже сказал, к void * относятся по-особому. void ** нет.

dbush 19.03.2022 21:16

Другие вопросы по теме