Приведение целого числа к указателю функции в сигнальном коде-почему это работает?

Я читаю книгу (расширенное программирование в среде UNIX), и я прохожу раздел о сигналах.

при использовании функции сигнала:

void (*signal(int signo, void (*func)(int)))(int);

параметр func может быть указателем на функцию, определенную пользователем, или SIG_ERR, SIG_DFL или SIG_IGN.

мой вопрос не в UNIX части этого, но я хотел дать фон. Что я действительно хочу знать, так это то, что в книге говорится, что эти константы defiend as:

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

и тому подобное для 0 и 1.

теперь у меня есть некоторые приличные догадки, но чтобы сэкономить время-может кто-нибудь сказать мне, что, черт возьми, это делает и почему это работает?

кроме того, есть... э... чище? способ написать это, предполагая, что я использую C++ и взаимодействую с этим C API?

3 ответов


это приведение целого числа к указателю на функцию;* значения заполнителей, по-видимому, выбраны так, чтобы они никогда не могли столкнуться со значениями указателей реальных функций. Реализация signal предположительно, затем проверяет входной параметр для этих специальных значений.


* стандарт C допускает это (см. 5), хотя в нем говорится, что результаты определяются реализацией. Очевидно, что авторы ОС способны контролируйте определенные реализацией аспекты этого, так что все в порядке.

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

это ставит под -1 к указателю на функцию (а именно на функцию, которая ничего не принимает и ничего не возвращает). Это сделает SIG_ERR всегда быть недопустимым и отличным от NULL.


Ну, это определить SIG_ERR как указатель на функцию void, принимающую любое количество аргументов с адресом -1. SIG_DFL имеет адрес 0, а SIG_IGN имеет адрес 1. Это просто специальные значения для исходной функции обработки сигналов, и эти адреса, вероятно, являются деталями реализации, которые вам не нужны. Просто используйте макросы, любезно определенные для вас, и вы будете хороши.

Если вы хотите, чтобы он чище-объявите свои собственные функции, например функцию, которая делает ничего и игнорирует сигнал, и использует указатель на него вместо SIG_IGN...

но я сомневаюсь в каком-либо значении обработки сигнала в коде C++. По какой-то причине программисты C++ любят обертывать абсолютно все, даже этот простой и прямой C API.