Почему я не могу вызвать функцию (обработчик сигнала), возвращенную сигналом функции? - PullRequest
1 голос
/ 28 марта 2019

После выяснения сигнатуры функции signal я изменил пример, приведенный в https://en.cppreference.com/w/c/program/signal.

Но почему я не могу вызвать функцию (обработчик сигнала), возвращаемуюsignal, вместо этого я могу назвать его direclty?


void (*signal( int sig, void (*handler) (int))) (int);

Функция signal возвращает указатель на функцию, которая является void (*)(int).

Возвращаемое значение

Предыдущий обработчик сигнала при успехе или SIG_ERR при ошибке (настройка обработчика сигнала может быть отключена в некоторых реализациях).

#include <signal.h>
#include <stdio.h>

void signal_handler(int signal)
{
    printf("hahahah\n");
}

int main(void)
{
    void (*f1)(int);
    f1 = signal(SIGINT, signal_handler);
    f1(3);  //Get signal SIGSEGV and failed
//    signal_handler(3); //OK
    raise(SIGINT);

}

Я знаю, что это может показаться бессмысленным вопросом, но дело в том, f1 указывает на signal_handler, поэтому вызов f1(3) подобен вызову signal_handler(3), я не понимаю, почему последнийвсе в порядке, но не первое, я думаю, что не должно быть никаких "уловок" между этими двумя вызовами функций.

Ответы [ 2 ]

1 голос
/ 28 марта 2019

Существует как минимум 3 значения, которые signal() может возвращать, которые не являются указателями на реальные функции:

  1. SIG_DFL - обычно ((void (*)(int))0)
  2. SIG_IGN -обычно ((void (*)(int))1)
  3. SIG_ERR - обычно ((void (*)(int))-1)

При запуске программы сигналы находятся либо в режиме SIG_IGN, либо SIG_DFL;впоследствии вы можете установить для них другое значение.

Когда вы вызываете f1 = signal(SIGINT, signal_handler);, вы получаете один из SIG_DFL и SIG_IGN - и ни один из них не является указателем на вызываемую функцию (даже если ихтип - указатель на функцию правильного типа).

1 голос
/ 28 марта 2019

В следующей строке:

f1 = signal(SIGINT, signal_handler);

f1 назначен предыдущий обработчик сигнала (который не является signal_handler в коде), который не может быть указателем нафункция, которую вы можете вызывать с аргументом int.

Чтобы добиться эффекта, вам нужно определить второй обработчик сигнала и присвоить ему f1 после указанной выше строки.

Примерно так:

#include <signal.h>
#include <stdio.h>

void signal_handler2(int signal)
{
    printf("hahahah2222\n");
}

void signal_handler(int signal)
{
    printf("hahahah\n");
}

int main(void)
{
    void (*f1)(int);
    f1 = signal(SIGINT, signal_handler);
    f1 = signal(SIGINT, signal_handler2);
    f1(3);  //Success
    signal_handler2(3); //OK
    raise(SIGINT);    
}

Вывод:

hahahah
hahahah2222
hahahah2222

См. Live Демо

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...