2011-12-07 39 views
10

我正在讀一本書(UNIX環境下的高級編程),我正在閱讀有關信號的部分。在信號代碼中將整數轉換爲函數指針 - 爲什麼這會起作用?

當使用信號函數:

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

參數,FUNC,可以是一個指針,指向由用戶定義的功能,或者它可以是SIG_ERR,SIG_DFL或SIG_IGN。

我的問題不在UNIX的UNIX部分,但我想給背景。我真正想知道的是,這本書指出,這些常量defiend爲:

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

等以0和1

現在,我有一些不錯的猜測,但爲了節省時間 - 有人能告訴我這是怎麼回事,爲什麼它有效?

另外,有沒有......呃......清潔劑?寫這個假設我正在使用C++並與這個C API交互的方式?

回答

11

它將整數轉換爲函數指針; *佔位符值大概是選擇的,以便它們永遠不會與真實函數指針的值相沖突。大概是signal的實現然後檢查這些特殊值的輸入參數。


*儘管它說結果是實現定義的,C標準允許這樣做(見6.3.2.3 p.5)。顯然,操作系統的作者能夠控制這個實現定義的方面,所以一切都很好。

+0

啊,所以它是一個函數指針有意僞造(但定義)的地址。我認爲它看起來像那樣,但由於某種原因它似乎是錯誤的。謝謝! –

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

這就引起-1的指針的函數(即需要什麼,並沒有返回值的函數)。這將使SIG_ERR始終無效,並且與NULL不同。

2

那麼,它確實將SIG_ERR定義爲指向void函數的指針,接受地址爲-1的任意數量的參數。 SIG_DFL的地址爲0,SIG_IGN的地址爲1.這些只是原始信號處理函數的特殊值,這些地址可能是您不應關心的實現細節。只需使用爲您定義的宏,您就會很好。

如果你想更乾淨 - 聲明自己的功能,例如功能,什麼也不做,忽略信號,並使用指針來代替它的SIG_IGN ...

但我懷疑包裹中的信號處理的任何值在C++代碼中。出於某種原因,C++程序員喜歡將所有東西都包裝起來,即使是簡單直接的C API。

相關問題