小議C#語言對整數的越界檢查

來源:互聯網
上載者:User

在C/C++中,整數變數的膚質是從來不進行越界檢查的,於是你可以給一個int變數成功賦予比INT_MAX(C/C++中定義的int的最大值)都大的數字,或者給不帶正負號的整數賦予一個負數值,結果就是值會被暴力塞到對應變數的空間內,因此二進位中多餘的高位可能會被剪掉。

 

事實上C語言標準並沒有強制這樣做,但是C語言的具體執行通常都會這樣的。

 

可以參考C語言標準4.7  Integral conversions

參考連結:http://www.slac.stanford.edu/BFROOT/www/Computing/Environment/Standards/C++/cd2/conv.html

 

 

範例程式碼:

//======= C/C++代碼 =======

 

cout << "INT_MAX: " << INT_MAX << endl;

//4294967297 (十六進位:0x100000001(33位))

int i1 = 0x100000001;

int i2 = 4294967297;

cout << i1 << endl;

cout << i2 << endl;

 

cout << "UINT_MAX: " << UINT_MAX << endl;

//-1的反碼值為:0xFFFFFFFF

unsigned int c = -1;

cout << c <<endl;

 

可以看到,第一段,我們將33位的一個數字賦給只能存放32位的int變數,於是最高位1被剪掉了,只有下中間一大堆0和最後一個1,所以最後變數輸出為1。第二段我們把-1賦值給一個無符號int,由於-1的反碼所有位都是1,所以最後輸出無符號int的最大值。

 

結果:

INT_MAX: 2147483647

1

1

UINT_MAX: 4294967295

4294967295

 

當然在C#中,常量越界會引發編譯錯誤(即使是用了強制轉換),如下:

 

 

正如Visual Studio的錯誤提示所說的,我們可以使用C#中的unchecked關鍵字來取消這樣的限制,如下代碼:

int i = unchecked((int)0x100000001);

uint ui = unchecked((uint)-1);

 

Console.WriteLine(i);

Console.WriteLine(ui);

 

這樣會成功輸出:

1

4294967295

 

上面講的是常量聲明中的越界檢查。當然,變數之間的強制轉換預設不會進行越界檢查的,所以還可以有另一種方法來實現上面代碼的功能,就是用變數之間的強制轉換:

//不直接使用常量

long i_long = 0x100000001;

int i_signed = -1;

 

int i = (int)i_long;

uint ui = (uint)i_signed;

 

Console.WriteLine(i);

Console.WriteLine(ui);

 

輸出會和上面一樣。

 

當然上面這些代碼的溢出都會悄悄發生不會被覺察,在某些時候可能會誘發Bug的出現,所以可以使用checked關鍵字來捕獲溢出錯誤(通過在catch中捕獲OverflowException),如下代碼:

long i_long = 0x100000001;

int i_signed = -1;

 

checked

{

    try

    {

        int i = (int)i_long;

        uint ui = (uint)i_signed;

 

        Console.WriteLine(i);

        Console.WriteLine(ui);

    }

    catch (OverflowException)

    {

        Console.WriteLine("溢出錯誤");

    }

}

 

上面代碼因為在checked塊內,所以會檢查運算(或者轉換)中的溢出情況,當有溢出發生後,OverflowException異常會被拋出。

 

如果你想在工程範圍內預設進行變數強制轉換的溢出檢查,可以在Visual Studio工程屬性中的Build選項中,選“進階”,選中“檢查運算溢出”。

 

這樣的話工程內所有代碼就好像在checked塊中運行了。如果某處不需要檢查溢出,則用unchecked關鍵字。

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.