POSIX相容的平台上,SIGFPE是當一個行程執行了一個錯誤的算術操作時傳送給它的訊號。SIGFPE的符號常數標頭檔signal.h中定義。因為在不同平台上,訊號數字可能變化,因此常使用訊號名稱。[1]

SIGFPE
描述錯誤的算術操作
預設動作行程異常終止
SA_SIGINFO宏
FPE_INTDIV 整數除以零
FPE_INTOVF 整數上溢
FPE_FLTDIV 浮點除以零
FPE_FLTOVF 浮點上溢
FPE_FLTUND 浮點下溢
FPE_FLTRES 浮點結果不准
FPE_FLTINV 無效浮點操作
FPE_FLTSUB 浮點下標越界

語源

SIG是訊號名的通用字首FPEfloating-point exception(浮點異常)的首字母縮略字。產生SIGFPE訊號時並非一定要涉及浮點算術,之所以不修改名字是因為這麼做會破壞向下相容性

描述

導致SIGFPE被傳送給行程的原因有很多。一個常見的例子是由於一個意外輸入導致的溢位,或者在程式構造中的錯誤。

SIGFPE可以被處理。也就是說,程式設計師可以指定他們在接收到訊號時想要的動作,例如呼叫一個子程式,忽略事件等。

在特定情形下,忽略SIGFPE可能導致程式出現意料之外的行為,包括但不限於由於不斷重試違規操作而導致程式掛起。但是,忽略並非由計算造成的SIGFPE訊號是安全的,例如通過kill系統呼叫傳送的那些。

一個通常的疏忽是認為除以零是SIGFPE的唯一來源。在一些架構上(包括IA-32[來源請求]),使用INT_MIN(最小的可以被表示的負整數值)除以-1的整數除法也會觸發這個訊號,因為商是一個無法被表示的正數。(比如8位元有符號整數可以表示-128、+127和它們之間的整數。-128÷-1=+128 > +127,因此無法被表示而產生溢位並觸發此訊號)

例子

這是一個嘗試執行一個稱為整數除以零,或FPE_INTDIV的錯誤算術運算的ANSI C程式的例子。

int main()
{
       int x = 42/0;
       return 0; /* Never reached */
}

在一個執行LinuxIA-32上編譯執行,產生下列內容:

$ gcc -o sigfpe sigfpe.c
sigfpe.c: In function ‘main’:
sigfpe.c:3: warning: division by zero
$ ./sigfpe
Floating point exception (core dumped)

一個來自gdb棧跟蹤顯示在main函式中發生了SIGFPE訊號:

Program received signal SIGFPE, Arithmetic exception.
0x08048373 in main ()

參考

參閱