2017-02-17 22 views
3

Я пришел к этому вопросу, когда написал один «непреднамеренный» фрагмент кода и скомпилировал его и получил желаемое поведение. Позже я заметил странность изменения и понял, что я использовал полный обратный порядок выполнения typedef указателей функций. Теперь я смущен, если «непреднамеренная» ошибка на самом деле синтаксически правильная.is * обязательно при выполнении typedef указателя функции?

Обычная конвенция:

typedef void* (*_malloc_fail_handler_ptr)(int) __attribute__ ((unused)); 
_malloc_fail_handler_ptr _malloc_fail_handler = NULL; 

Мой "непреднамеренное" Код:

typedef void* (_malloc_fail_handler_ptr)(int) __attribute__ ((unused)); 
_malloc_fail_handler_ptr* _malloc_fail_handler = NULL; 

ответ

5

Это правильный синтаксис. Для второго случая тип _malloc_fail_handler_ptr является функцией, а не указателем функции. Тогда тип _malloc_fail_handler_ptr* является указателем на функцию. Таким образом, для 1-го и 2-го случаев тип переменной _malloc_fail_handler такой же.

+0

Да, хотя имя должно быть изменено на _malloc_fail_handler_func или что-то такое, чтобы имя соответствовало тому, что это такое :). (nit picking) – Rob

+0

Это на самом деле довольно полезно, поскольку позволяет явно объявлять функции, реализующие интерфейс, как это делается, например, в 'extern malloc_fail_handler_t implementationor;'. – doynax

3

Единственная проблема со вторым является именование:

typedef void* (*_malloc_fail_handler_ptr)(int) __attribute__ ((unused)); 

Там, _malloc_fail_handler_ptr является указатель функция принимает int и возвращение void*.

typedef void* (_malloc_fail_handler_ptr)(int) __attribute__ ((unused)); 

Здесь _malloc_fail_handler_ptr функция принимает int и возвращение void*. Это тип функции, а не тип указателя. Таким образом, суффикс _ptr вводит в заблуждение. Но, как и любой (в C++, без ссылки), вы всегда можете написать T*, чтобы получить указатель на T, так что это работает.


Упрощая все, чтобы избежать неловкого синтаксис функции, ваш вопрос сводится к тому:

typedef int* ptr; 
ptr x = NULL; 

против:

typedef int ptr; 
ptr* x = NULL; 

Оба синтаксически хорошо, но второй один довольно обманчиво по имени.