Кастинг целое для функции указателя в сигнальном коде - зачем это работает?
Я читаю книгу (Расширенное программирование в среде UNIX), и я просматриваю раздел о сигналах.
При использовании функции сигнала:
void (*signal(int signo, void (*func)(int)))(int);
параметр func может быть указателем на функцию, определенную пользователем, или может быть SIG_ERR, SIG_DFL или SIG_IGN.
Мой вопрос не в части UNIX этого, но я хотел дать задний план. Я действительно хочу знать, что в книге указано, что эти константы определяются как:
#define SIG_ERR (void (*)())-1
и т.п. для 0 и 1.
Теперь у меня есть приличные догадки, но чтобы сэкономить время - может кто-нибудь скажет мне, что это делает и почему он работает?
Кроме того, есть ли... erm... cleaner? способ написать это, предполагая, что я использую С++ и взаимодействую с этим C API?
Ответы
Ответ 1
Он отличает целое число к указателю на функцию; * значения заполнитель предположительно выбраны так, что они никогда не могут столкнуться со значениями указателей реальных функций. Реализация signal
предположительно затем проверяет входной аргумент для этих специальных значений.
* Стандарт C позволяет это (см. 6.3.2.3 с .5), хотя он говорит, что результаты определены реализацией. Очевидно, что авторы ОС могут контролировать определенные в реализации аспекты, поэтому все нормально.
Ответ 2
#define SIG_ERR (void (*)())-1
Это приводит к -1
указателю на функцию (а именно функцию, которая ничего не принимает и ничего не возвращает). Это приведет к тому, что SIG_ERR
всегда будет недействительным и отличается от NULL
.
Ответ 3
Ну, он определяет SIG_ERR
как указатель на функцию void, принимающую любое количество аргументов с адресом -1. SIG_DFL
имеет адрес 0 и SIG_IGN
имеет адрес 1. Это только специальные значения для функции обработки исходного сигнала, и эти адреса, вероятно, являются деталями реализации, о которых вам не нужно заботиться. Просто используйте макросы, любезно определенные для вас, и вы будете хорошо.
Если вы хотите, чтобы он был чище - объявите свои собственные функции, например функцию, которая ничего не делает и игнорирует сигнал, и используйте указатель на нее вместо SIG_IGN...
Но я сомневаюсь в какой-либо ценности в обработке обработки пакетов в коде С++. По какой-то причине программисты на C++ любят обертывать абсолютно все, даже этот простой и прямой C API.