Приведение целого числа к указателю функции в сигнальном коде-почему это работает?
Я читаю книгу (расширенное программирование в среде 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.