2013-08-06 1 views
1

Я не понимаю, почему компилятор предупреждает меня о передаче несовместимого типа указателя в этом коде: (в этом контексте какая разница между void * и void **) (я не знаю, если это имеет значение, но я использую gnu99 C версия)Переход к void ** вместо void * заставляет компилятор жаловаться на типы, почему?

void someFunc(void ** foo) { 
    printf("%s\n", *foo); 
} 

int main() { 

    char * text = "some text"; 
    someFunc(&text); 

    return 0; 
} 

и в этом не

void someFunc(void * foo) { 
    printf("%s\n", foo); 
} 

int main() { 

    char * text = "some text"; 
    someFunc(text); 

    return 0; 
} 

заранее спасибо

ответ

6

void * является тип, неявно конвертируется в любой тип указателя объекта и из него. void ** нет - так что пока вы можете назначить char * к void *, вы можете не сделать то же самое с char ** и void **.

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

+0

ОК, понятно, поэтому, когда у меня есть своп-функция, например void swap ( ** a, ** b) вместо указателей вместо swap. Если я хочу сделать его общим (тип нечувствительный или что-то еще), что это правильный способ сделать это? – Sasquash

+0

@ Sasquash Извините, я не понимаю, что вы имеете в виду. Достаточно иметь 'T *', чтобы поменять два значения типа 'T'. –

1

Чтобы исправить код во втором примере, вы можете выполнить одно из следующих действий:

// Solution A, preferred: 
void someFunc(char * foo) { 
    printf("%s\n", foo); 
} 

int main() { 

    char * text = "some text"; 
    someFunc(text); 

    return 0; 
} 

В А вы говорите компилятору, что параметр передается является указателем на символ. Я не пробовал решение B, должен работать, но зачем использовать пустоты, если они НЕ абсолютно необходимы.

// Solution B, should work but a purist might object: 
void someFunc(void * foo) { 
    printf("%s\n", foo); 
} 

int main() { 

    char * text = "some text"; 
    someFunc((void *) text); 

    return 0; 
} 

В этом вопросе нет никакой очевидной причины использовать двойную PTR, поэтому решение A для вашего второго примера, вероятно, путь.