以下例子取自《深入理解計算機系統》。
考慮如下的C語言代碼:
1 #include<stdio.h>
2
3 typedef unsigned char* byte_pointer;
4
5 void show_bytes(byte_pointer pointer, int size){
6 int i = 0;
7 for (i = 0; i < size; ++i){
8 printf("%.2x", pointer[i]);
9 }
10 }
11
12 int main(){
13 short sx = -12345;
14 unsigned uy = sx;
15 printf("uy = %u:\t", uy);
16 show_bytes((byte_pointer)&uy, sizeof(unsigned));
17 printf("\n");
18 }
該程序在小端法的機器上會產生如下輸出:uy = 4294954951: c7cfffff
這表明當把short轉換成unsigned 時,我們先改變大小,之後在完成從有符號到無符號的轉換。也就是說(unsigned)sx等價於(unsigned)(int)sx,求值得到4294954951,而不等價於(unsigned)(unsigned short)sx,後者求值得到53191。事實上,這個規則是C語言標准要求的。
另外,當執行一個運算時,如果它的一個運算數是有符號的而另一個是無符號的,那麼C語言會隱式地將有符號參數強制類型轉換為無符號參數,並假設這兩個數都是非負的,來執行這個運算。這種方法對於標准的算數運算並無多大差異,但是對於<和>這樣的關系運算符來說,它會導致非直觀的結果。
例如對(-1 < 0U)這個表達式求值,其結果為0。因為第二個運算數是無符號的,第一個運算數會被隱式地轉換為無符號數,因此表達式就等價為(4294967295U < 0U),這個答案顯然是錯的。
基於同樣的理由,我們考慮一下代碼:
1 double sum_elements(double a[], unsigned length){
2 int i;
3 double result = 0;
4 for (i = 0; i <= length - 1; ++i){
5 result += a[i];
6 }
7 return result;
8 }
當傳入的length=0時,會產生越界錯誤。