Нужен ли Cast to void **? - PullRequest
       13

Нужен ли Cast to void **?

4 голосов
/ 05 февраля 2010

У меня есть компилятор, который жалуется (предупреждает) о следующем.

Я что-то упустил? Потому что я думал, что для этого не нужен актерский состав

char* CurrentCh  = some ptr value;
int size;

size = func(&CurrentCh);

с функцией, определенной следующим образом

int func(void** ptr);

Предупреждение компилятора:

передача аргумента 1 из 'func' из несовместимого типа указателя

Thx

Ответы [ 4 ]

7 голосов
/ 05 февраля 2010

В C вы можете передать любой тип указателя в функцию, которая ожидает пустоту *. Он говорит: «Мне нужен указатель на что-то, не важно, на что он указывает». В то время как void ** говорит: «Мне нужен указатель на void *, а не указатель на другой тип указателя».

4 голосов
/ 05 февраля 2010

В C void * - это тип общего указателя. Но void ** не является универсальным типом указатель-указатель! Если вы хотите иметь возможность передавать указатель на указатель обычным способом, вы должны использовать void * в любом случае:

#include <stdio.h>

void func(void *ptr)
{
    char **actual = ptr;
    const char *data = *actual;
    printf("%s\n", data);
}

int main(void)
{
    char *test = "Hello, world";
    func(&test);
    return 0;
}
3 голосов
/ 05 февраля 2010

Приведение необходимо, так как то, что вы делаете, является формой наказания типа: вы переосмысливаете память, на которую указывает от char * до void *.

Для этих типов стандарт C гарантирует, что это действительно работает, так как char * и void * имеют одинаковое представление. Для других комбинаций типов это может быть не так.

Соответствующими частями стандарта являются раздел 6.2.5, §27

.

Указатель на void должен иметь такой же представление и выравнивание требования в качестве указателя на тип персонажа. Аналогично, указатели к квалифицированным или неквалифицированным версиям совместимых типов должны иметь такое же представление и выравнивание требования. Все указатели на типы конструкций должны быть одинаковыми представление и выравнивание требования как друг к другу. Все указатели на типы объединений должны иметь такое же представление и выравнивание требования как друг к другу. указатели для других типов не нужно иметь то же самое представление или выравнивание требования.

и менее актуален (но, возможно, также интересен) раздел 6.3.2.3, §7

Указатель на объект или неполный тип может быть преобразован в указатель на другой объект или неполный тип. Если результирующий указатель не правильно выровнен для тип, поведение не определено. В противном случае, когда преобразуется обратно, результат должен сравниваться равным оригинальный указатель Когда указатель на Объект преобразуется в указатель на тип символа, результат указывает на младший адресуемый байт объект. Последовательные приращения результат, вплоть до размера объекта, указатели на оставшиеся байты объекта.

Все остальное зависит от реализации.

0 голосов
/ 05 февраля 2010

В C любой указатель может быть уменьшен до void *, но не void **. Вам понадобится явное приведение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...