2013-07-11 2 views
0

Я видел эту строку в signal.h в /usr/include/sys/ на моем mac. Исходя из его использования в качестве возвращаемого типа функции signal, я ожидал бы, что SIG_ERR будет указателем на функцию, которая принимает целочисленный ввод и возвращает void. Но макроразложение SIG_ERR, кажется, вычитает 1 из типа указателя функции, который я нашел странным. Как C разобрать его?Вычитание 1 из функции pointer

#define SIG_ERR   ((void (*)(int))-1) 

ответ

7
((void(*)(int)) -1) 

не вычесть 1 из указателя функции, что она делает это литой постоянное значение -1, чтобы указатель на функцию.

В качестве примечания стороны добавление или вычитание из указателя функции не допускается в ISO C и может быть выполнено только as a (somewhat peculiar) gcc extension, который в основном обрабатывает его, как если бы это был указатель на символ;

В GCC операции сложения и вычитания разрешены по указателям типа void и указатели на функции. Как правило, ISO C не допускает арифметики для таких указателей, потому что размер «пустоты» является глупой концепцией и зависит от того, на что указывает указатель. Чтобы облегчить такую ​​арифметику, GCC рассматривает размер ссылочного объекта как один байт.

+0

А, хорошо! Спасибо за ответ. – gkb0986

1

На the manual page of signal() гласит:

сигнал() функция возвращает предыдущее значение обработчика сигнала или SIG_ERR по ошибке.

Так что этот -1 «указатель функции» просто является значением показателя ошибки.

Конечно, вычитание -1 из указателя не имеет смысла на большинстве платформ из-за ограничений выравнивания; указатель обычно будет кратным 4 байтам.

Смежные вопросы