2016-08-01 2 views
0

В чем разница между void (*xmlHashScanner)(void *payload, void *data, xmlChar *name) и void *xmlHashScanner(void *payload, void *data, xmlChar *name) в C?
Почему они ведут себя по-другому?разница между void (* xmlHashScanner) и void * xmlHashScanner


xmlHashScanner является пользовательской функцией в библиотеке libxml2.
При попытке переопределить эту функцию с немного иным прототипом: void *xmlHashScanner вместо void (*xmlHashScanner) У меня есть следующее сообщение об ошибке:

error: ‘xmlHashScanner’ redeclared as different kind of symbol 
void *xmlHashScanner(void *payload, void *data, xmlChar *name) 
    ^
In file included from /usr/include/libxml2/libxml/parser.h:18:0, 
       from /home/solar/Bureau/parser/src/diam_dict.c:12: 
/usr/include/libxml2/libxml/hash.h:88:16: note: previous declaration of ‘xmlHashScanner’ was here 
typedef void (*xmlHashScanner)(void *payload, void *data, xmlChar *name); 

Интересно, что разница между двумя из них.

+1

Можете ли вы объяснить различные модели поведения? –

+0

@ScottHunter Я сказал, что они разные, потому что один компилируется, а другой нет. – cheater

+0

'void (* xmlHashScanner)()' является указателем на функцию void. 'void * xmlHashScanner()' - функция, возвращающая указатель void. – Arkadiy

ответ

1
void (*xmlHashScanner)(void *payload, void *data, xmlChar *name) 

объявляет xmlHashScanner как указатель на функцию возвращающегося void, в то время как

void *xmlHashScanner(void *payload, void *data, xmlChar *name) 

объявляет xmlHashScanner как функция, возвращающая указатель на void.

В обоих декларации и выражения синтаксиса, одинарный * оператор имеет более низкий приоритет, чем постфиксных [] индексных и () вызова функции операторов, так

T *a[N];  // a is an N-element array of pointer to T 
T (*a)[N]; // a is a pointer to an N-element array of T 
T *f();  // f is a function returning a pointer to T 
T (*f)(); // f is a pointer to a function returning T 
+0

Я думал, что многому научился, но теперь я чувствую, что я только что нашел% 0,1 из этого ... До сих пор остается большой путь. – cheater

+0

@cheater: см. Раздел 6.7 [последний онлайн-проект] (http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf) стандарта C для полного описания синтаксис объявления. 6.7.6 (Деклараторы) - это то, где вещи становятся действительно уродливыми^H^H^H^H интересными. –

3

void (*xmlHashScanner)(...) прототип для функции указателя не возвращающей ничего (Недействительными), тогда как void *xmlHashScanner(...) является прототипом функции возвращает пустоту *

0

Таким образом, вы сравниваете этот:

void *xmlHashScanner(void *payload, void *data, xmlChar *name); 

при этом:

typedef void (*xmlHashScanner)(void *payload, void *data, xmlChar *name); 

Первый - это объявление для функции, а второе - typedef (определяет тип). Функция и тип - это совершенно разные вещи; они используются для различных целей:

  • Функция может быть вызвана
  • Тип может быть использован для создания переменной, которая затем может участвовать в расчетах

Это то, что означает, что ваш компилятор по «другой вид символа» - нет контекста (если случайно), где эти фрагменты кода могут делать что угодно. Рассмотрим, например, фрагменты кода - 42 и &&. У них нет ничего общего - они два разных видов вещей.

Чтобы понять детали декларации, которые немного запутывают, используйте правило right-left, которое также реализовано here.

  • typedef void (*xmlHashScanner)(whatever)xmlHashScanner означает тип является указателем на функцию с любыми аргументами возвращающегося void
  • void *xmlHashScanner(whatever)xmlHashScanner означает функция с любыми аргументами, которая возвращает void *
Смежные вопросы