C語言的隱式類型轉換


看了一篇博文,該文章中有如下描述

 1 #include <stdio.h>  
 2   
 3 int main()  
 4 {  
 5     unsigned short a = 1;  
 6     unsigned short b = 0;  
 7    
 8     if (a < (b-1)) //a和b-1的結果-1都被轉換為int類型進行比較,1<-1,顯然false  
 9     {  
10         printf("in if\n");  
11     }  
12   
13     return 0;  
14       
15 }  

預期結果時打印“in if”,但實際運行時卻發現啥都沒有輸出。改為如下代碼就可以正常輸出“in if”,此時與預期相符

 1 #include <stdio.h>  
 2   
 3 int main()  
 4 {  
 5     unsigned short a = 1;  
 6     unsigned int b = 0;  
 7    
 8     if (a < (b-1)) //b-1的結果-1,被轉換為0xffffffff,1<0xffffffff,顯然true啊  
 9     {  
10         printf("in if\n");  
11     }  
12   
13     return 0;  
14       
15 }  

使用匯編,直接對比兩者結果(公司安全不讓發送外網圖片..),發現主要差異在如下5行,前四行中對short進行了擴展,由2字節擴展為4字節,高位填充0。導致運行結果與與預期不符合的原因就在第5行:jge 8048461 

 1 08048425 <main>:
 2  8048425:      8d 4c 24 04              lea    0x4(%esp),%ecx
 3  8048429:      83 e4 f0                 and    $0xfffffff0,%esp
 4  804842c:      ff 71 fc                 pushl  -0x4(%ecx)
 5  804842f:      55                       push   %ebp
 6  8048430:      89 e5                    mov    %esp,%ebp
 7  8048432:      51                       push   %ecx
 8  8048433:      83 ec 14                 sub    $0x14,%esp
 9  8048436:      66 c7 45 f6 01 00        movw   $0x1,-0xa(%ebp) 10  804843c:      66 c7 45 f4 00 00        movw   $0x0,-0xc(%ebp) 11  8048442:      0f b7 45 f6              movzwl -0xa(%ebp),%eax 12  8048446:      0f b7 55 f4              movzwl -0xc(%ebp),%edx 13  804844a:      83 ea 01                 sub    $0x1,%edx
14  804844d:      39 d0                    cmp    %edx,%eax
15  804844f:      7d 10                    jge    8048461 <main+0x3c>
16  8048451:      83 ec 0c                 sub    $0xc,%esp
17  8048454:      68 00 85 04 08           push   $0x8048500
18  8048459:      e8 a2 fe ff ff           call   8048300 <puts@plt>
19  804845e:      83 c4 10                 add    $0x10,%esp
20  8048461:      b8 00 00 00 00           mov    $0x0,%eax
21  8048466:      8b 4d fc                 mov    -0x4(%ebp),%ecx
22  8048469:      c9                       leave  
23  804846a:      8d 61 fc                 lea    -0x4(%ecx),%esp
24  804846d:      c3                       ret    
25  804846e:      66 90                    xchg   %ax,%ax

 

匯編中的數值是沒有符號之分的,但指令是有符號分別的,上述使用的jge即是有符號比較的方式,導致比較結果為:if (1<-1),為false,不會打印字符串

指令 含義 運算符號
jbe unsigned below or equal (lower or same) <=
jae unsigned above or equal (higher or same) >=
jb unsigned below (lower) <
ja unsigned above (higher) >
jle signed less or equal <=
jge signed greater or equal >=
jl signed less than <
jg signed greater than >


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM