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

Я читаю книгу (Расширенное программирование в среде 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.