char 高位擴展

Char轉爲int時高位符號擴展的問題

代碼示例: 
static get_utili(const char *p)
{
  int util;while (isspace((int)*p))   //跳過空格
    ++p;
  util = (int) *p++;}
現象&後果: 

當傳入的參數p指向的內容爲0x9A、0XAB等內容(最高位爲1)時,得到的int型變量util的值將會出錯,因爲char會進行符號擴展,使得0x9A(十進制的154)變成了-102。會造成程序運行時的數據處理錯誤。

Bug分析: 

char符號擴展是與編譯器相關的,但在x86平臺上,對於任何主流的編譯平臺,char總是進行符號擴展的。上述代碼在將char型的*p賦給int型變量util的時候,需要先進行char型到unsigned char型的轉換,以避免按照char的最高位進行符號擴展
上述出錯代碼的符號擴展過程如下:
因爲要擴展的短數據類型爲有符號數的-- char x=10011100b(即0x9A)
因而在int y=(int)x時--進行符號擴展,即短數據類型的符號位填充到長數據類型的高字節位(比短數據類型多出的那一部分),則y的值爲11111111 10011100b(變成了十進制的-102);
但是,將要擴展的短數據類型變成無符號數後--unsigned char x=10011100b(即0x9A)
在 int y=(int)x時--進行擴展的時候是以零擴展,即用零來填充長數據類型的高字節位,則y的值應爲00000000 10011100b(十進制的154)。

正確代碼: 
util = (int) *p++;改成
util = (int)(unsigned char) *p++
Bug定位: 

該bug是在code review的過程中發現的。
char符號擴展的問題,如果在測試時沒有構造相應的case,就會很難被發現。面對這類問題,細緻的code review是必不可少的,不管是通過code review直接發現問題還是通過review來豐富相應case的構造,code review都應該是一個不可缺少的環節。

編程建議: 

1. 與此bug擴展的相關知識點的參考資料地址
《編程卓越之道》的第一卷:深入理解計算機中,有一節很爲詳細的介紹了符號擴展、零擴展的相關內容,具體章節爲2.7 符號擴展,零擴展,以及縮減。下載地址可參見
http://homepage.mac.com/randyhyde/webster.cs.ucr.edu/
www.writegreatcode.com/
2. 如果必須要進行類型轉換的話,建議用c++標準的static_cast

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章