鱼C论坛

 找回密码
 立即注册
查看: 1366|回复: 5

[已解决]关于devc++和vc6.0自加运算符结果不同的原因

[复制链接]
发表于 2021-10-20 21:32:33 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
#include <stdio.h>
int main()
{
        int i=3,j=3,x,y;
        x=(i++)+(i++)+(i++);
        y=(++j)+(++j)+(++j);
        printf("%d\t%d\t",x,y);
        printf("%d\t%d\t",i,j);
        return 0;
}
通过DevC++ 的运算结果为12 16 6 6
通过VC6.0的运算结果为9 16 6 6
想知道为什么 二者结果不同- -       
https://www.wenmi.com/article/q02a4w03yqga.html
这里有一个相关内容的链接 但是没有讲述上述这种情况,所以来此求助
最佳答案
2021-10-21 11:55:33
本帖最后由 jackz007 于 2021-10-21 12:28 编辑

        我分别使用 vc6.0 和 gcc 10.2.0 编译了这个源程序,并使用 OllyDBG 仔细跟踪了两个程序的反汇编代码,把算法过程用 C 语言进行了描述,可以看出,两个编译器产生代码的主要差异在于计算 x 过程的完全不同,计算 y 的过程二者完全相同。
  1. #include <stdio.h>

  2. void vc(void)
  3. {
  4.         int i = 3 , j = 3 , x , y ;
  5.         x = i + i + i             ;
  6.         i ++                      ;
  7.         i ++                      ;
  8.         i ++                      ;
  9.         j ++                      ;
  10.         j ++                      ;
  11.         y = j + j                 ;
  12.         j ++                      ;
  13.         y += j                    ;
  14.         printf("%d\t%d\t",x,y)    ;
  15.         printf("%d\t%d\n",i,j)    ;
  16. }

  17. void gcc()
  18. {
  19.         int i = 3 , j = 3 , x , y ;
  20.         x = i                     ;
  21.         i ++                      ;
  22.         x += i                    ;
  23.         i ++                      ;
  24.         x += i                    ;
  25.         i ++                      ;
  26.         j ++                      ;
  27.         j ++                      ;
  28.         y = j + j                 ;
  29.         j ++                      ;
  30.         y += j                    ;
  31.         printf("%d\t%d\t",x,y)    ;
  32.         printf("%d\t%d\n",i,j)    ;
  33. }

  34. int main(void)
  35. {
  36.         printf("-------- vc6.0 --------\n") ;
  37.         vc()                                ;
  38.         printf("-------- dev-c --------\n") ;
  39.         gcc()                               ;
  40. }
复制代码

        编译、运行实况
  1. D:\0002.Exercise\C>g++ -o x x.c

  2. D:\0002.Exercise\C>x
  3. -------- vc6.0 --------
  4. 9       16      6       6
  5. -------- dev-c --------
  6. 12      16      6       6

  7. D:\0002.Exercise\C>
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-10-21 11:35:40 | 显示全部楼层
编译器的原因吧,各编译器实现方法不同,编译结果也不同,所以建议不要用这种写法。

我试了下
用gcc编译结果是12 16 6 6
用calng 编译结果是 12 15 6 6,并且有警告。这里的y=15才是预期结果。
  1. PS F:\Repos\ccode> clang main.c -o main.exe
  2. main.c:6:11: warning: multiple unsequenced modifications to 'i' [-Wunsequenced]
  3.     x = (i++) + (i++) + (i++);
  4.           ^       ~~
  5. main.c:7:10: warning: multiple unsequenced modifications to 'j' [-Wunsequenced]
  6.     y = (++j) + (++j) + (++j);
  7.          ^       ~~
  8. 2 warnings generated.
  9. PS F:\Repos\ccode> ./main
  10. 12      15      6       6
  11. PS F:\Repos\ccode>  
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-10-21 11:55:33 | 显示全部楼层    本楼为最佳答案   
本帖最后由 jackz007 于 2021-10-21 12:28 编辑

        我分别使用 vc6.0 和 gcc 10.2.0 编译了这个源程序,并使用 OllyDBG 仔细跟踪了两个程序的反汇编代码,把算法过程用 C 语言进行了描述,可以看出,两个编译器产生代码的主要差异在于计算 x 过程的完全不同,计算 y 的过程二者完全相同。
  1. #include <stdio.h>

  2. void vc(void)
  3. {
  4.         int i = 3 , j = 3 , x , y ;
  5.         x = i + i + i             ;
  6.         i ++                      ;
  7.         i ++                      ;
  8.         i ++                      ;
  9.         j ++                      ;
  10.         j ++                      ;
  11.         y = j + j                 ;
  12.         j ++                      ;
  13.         y += j                    ;
  14.         printf("%d\t%d\t",x,y)    ;
  15.         printf("%d\t%d\n",i,j)    ;
  16. }

  17. void gcc()
  18. {
  19.         int i = 3 , j = 3 , x , y ;
  20.         x = i                     ;
  21.         i ++                      ;
  22.         x += i                    ;
  23.         i ++                      ;
  24.         x += i                    ;
  25.         i ++                      ;
  26.         j ++                      ;
  27.         j ++                      ;
  28.         y = j + j                 ;
  29.         j ++                      ;
  30.         y += j                    ;
  31.         printf("%d\t%d\t",x,y)    ;
  32.         printf("%d\t%d\n",i,j)    ;
  33. }

  34. int main(void)
  35. {
  36.         printf("-------- vc6.0 --------\n") ;
  37.         vc()                                ;
  38.         printf("-------- dev-c --------\n") ;
  39.         gcc()                               ;
  40. }
复制代码

        编译、运行实况
  1. D:\0002.Exercise\C>g++ -o x x.c

  2. D:\0002.Exercise\C>x
  3. -------- vc6.0 --------
  4. 9       16      6       6
  5. -------- dev-c --------
  6. 12      16      6       6

  7. D:\0002.Exercise\C>
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-10-21 15:03:00 | 显示全部楼层
本帖最后由 jackz007 于 2021-10-21 20:23 编辑

        相关反汇编代码分析
  1. ====================================================================================================================================================
  2. *                                                               vc6.0 - 编译                                                                       *
  3. ====================================================================================================================================================
  4. 00401000  /$  55                         push    ebp
  5. 00401001  |.  8BEC                       mov     ebp, esp
  6. 00401003  |.  83EC 10                    sub     esp, 0x10
  7. 00401006  |.  C745 F4 03000000           mov     dword ptr [ebp-0xC], 0x3                                   ;  i = 3
  8. 0040100D  |.  C745 F0 03000000           mov     dword ptr [ebp-0x10], 0x3                                  ;  j = 3
  9. 00401014  |.  8B45 F4                    mov     eax, dword ptr [ebp-0xC]                                   ;  x = i
  10. 00401017  |.  0345 F4                    add     eax, dword ptr [ebp-0xC]                                   ;  x = x + i
  11. 0040101A  |.  0345 F4                    add     eax, dword ptr [ebp-0xC]                                   ;  x = x + i
  12. 0040101D  |.  8945 FC                    mov     dword ptr [ebp-0x4], eax
  13. 00401020  |.  8B4D F4                    mov     ecx, dword ptr [ebp-0xC]
  14. 00401023  |.  83C1 01                    add     ecx, 0x1
  15. 00401026  |.  894D F4                    mov     dword ptr [ebp-0xC], ecx                                   ;  i = i + 1
  16. 00401029  |.  8B55 F4                    mov     edx, dword ptr [ebp-0xC]
  17. 0040102C  |.  83C2 01                    add     edx, 0x1
  18. 0040102F  |.  8955 F4                    mov     dword ptr [ebp-0xC], edx                                   ;  i = i + 1
  19. 00401032  |.  8B45 F4                    mov     eax, dword ptr [ebp-0xC]
  20. 00401035  |.  83C0 01                    add     eax, 0x1
  21. 00401038  |.  8945 F4                    mov     dword ptr [ebp-0xC], eax                                   ;  i = i + 1
  22. 0040103B  |.  8B4D F0                    mov     ecx, dword ptr [ebp-0x10]
  23. 0040103E  |.  83C1 01                    add     ecx, 0x1
  24. 00401041  |.  894D F0                    mov     dword ptr [ebp-0x10], ecx                                  ;  j = j + 1
  25. 00401044  |.  8B55 F0                    mov     edx, dword ptr [ebp-0x10]
  26. 00401047  |.  83C2 01                    add     edx, 0x1
  27. 0040104A  |.  8955 F0                    mov     dword ptr [ebp-0x10], edx                                  ;  j = j + 1
  28. 0040104D  |.  8B45 F0                    mov     eax, dword ptr [ebp-0x10]                                  ;  y = j
  29. 00401050  |.  0345 F0                    add     eax, dword ptr [ebp-0x10]                                  ;  y = y + j
  30. 00401053  |.  8B4D F0                    mov     ecx, dword ptr [ebp-0x10]
  31. 00401056  |.  83C1 01                    add     ecx, 0x1
  32. 00401059  |.  894D F0                    mov     dword ptr [ebp-0x10], ecx                                  ;  j = j + 1
  33. 0040105C  |.  0345 F0                    add     eax, dword ptr [ebp-0x10]                                  ;  y = y + j
  34. 0040105F  |.  8945 F8                    mov     dword ptr [ebp-0x8], eax
  35. 00401062  |.  8B55 F8                    mov     edx, dword ptr [ebp-0x8]
  36. 00401065  |.  52                         push    edx
  37. 00401066  |.  8B45 FC                    mov     eax, dword ptr [ebp-0x4]
  38. 00401069  |.  50                         push    eax
  39. 0040106A  |.  68 30704000                push    00407030                                                   ;  ASCII "%d\t%d\t"
  40. 0040106F  |.  E8 1E000000                call    00401092
  41. 00401074  |.  83C4 0C                    add     esp, 0xC
  42. 00401077  |.  8B4D F0                    mov     ecx, dword ptr [ebp-0x10]
  43. 0040107A  |.  51                         push    ecx
  44. 0040107B  |.  8B55 F4                    mov     edx, dword ptr [ebp-0xC]
  45. 0040107E  |.  52                         push    edx
  46. 0040107F  |.  68 38704000                push    00407038                                                   ;  ASCII "%d\t%d\t"
  47. 00401084  |.  E8 09000000                call    00401092
  48. 00401089  |.  83C4 0C                    add     esp, 0xC
  49. 0040108C  |.  33C0                       xor     eax, eax
  50. 0040108E  |.  8BE5                       mov     esp, ebp
  51. 00401090  |.  5D                         pop     ebp
  52. 00401091  \.  C3                         retn
  53. ====================================================================================================================================================
复制代码
  1. ====================================================================================================================================================
  2. *                                                            gcc 10.2.0 - 编译                                                                     *
  3. ====================================================================================================================================================
  4. 00401500  /$  55                         push    ebp
  5. 00401501  |.  89E5                       mov     ebp, esp
  6. 00401503  |.  83E4 F0                    and     esp, 0xFFFFFFF0
  7. 00401506  |.  83EC 20                    sub     esp, 0x20
  8. 00401509  |.  E8 02020000                call    00401710
  9. 0040150E  |.  C74424 1C 03000000         mov     dword ptr [esp+0x1C], 0x3                                  ; ||i = 3
  10. 00401516  |.  C74424 18 03000000         mov     dword ptr [esp+0x18], 0x3                                  ; ||j = 3
  11. 0040151E  |.  8B5424 1C                  mov     edx, dword ptr [esp+0x1C]                                  ; ||v1 = i
  12. 00401522  |.  8D42 01                    lea     eax, dword ptr [edx+0x1]                                   ; ||
  13. 00401525  |.  894424 1C                  mov     dword ptr [esp+0x1C], eax                                  ; ||i = i + 1
  14. 00401529  |.  8B4424 1C                  mov     eax, dword ptr [esp+0x1C]                                  ; ||v2 = i
  15. 0040152D  |.  8D48 01                    lea     ecx, dword ptr [eax+0x1]                                   ; ||
  16. 00401530  |.  894C24 1C                  mov     dword ptr [esp+0x1C], ecx                                  ; ||i = i + 1
  17. 00401534  |.  8D0C02                     lea     ecx, dword ptr [edx+eax]                                   ; ||x = v1 + v2
  18. 00401537  |.  8B4424 1C                  mov     eax, dword ptr [esp+0x1C]                                  ; ||v3 = i
  19. 0040153B  |.  8D50 01                    lea     edx, dword ptr [eax+0x1]                                   ; ||
  20. 0040153E  |.  895424 1C                  mov     dword ptr [esp+0x1C], edx                                  ; ||i = i + 1
  21. 00401542  |.  01C8                       add     eax, ecx                                                   ; ||x = x + v3
  22. 00401544  |.  894424 14                  mov     dword ptr [esp+0x14], eax                                  ; ||
  23. 00401548  |.  834424 18 01               add     dword ptr [esp+0x18], 0x1                                  ; ||j = j + 1
  24. 0040154D  |.  834424 18 01               add     dword ptr [esp+0x18], 0x1                                  ; ||j = j + 1
  25. 00401552  |.  8B4424 18                  mov     eax, dword ptr [esp+0x18]                                  ; ||y = j
  26. 00401556  |.  8D1400                     lea     edx, dword ptr [eax+eax]                                   ; ||y = y + j
  27. 00401559  |.  834424 18 01               add     dword ptr [esp+0x18], 0x1                                  ; ||j = j + 1
  28. 0040155E  |.  8B4424 18                  mov     eax, dword ptr [esp+0x18]                                  ; ||
  29. 00401562  |.  01D0                       add     eax, edx                                                   ; ||y = y + j
  30. 00401564  |.  894424 10                  mov     dword ptr [esp+0x10], eax                                  ; ||
  31. 00401568  |.  8B4424 10                  mov     eax, dword ptr [esp+0x10]                                  ; ||
  32. 0040156C  |.  894424 08                  mov     dword ptr [esp+0x8], eax                                   ; ||
  33. 00401570  |.  8B4424 14                  mov     eax, dword ptr [esp+0x14]                                  ; ||
  34. 00401574  |.  894424 04                  mov     dword ptr [esp+0x4], eax                                   ; ||
  35. 00401578  |.  C70424 00404000            mov     dword ptr [esp], 00404000                                  ; ||ASCII "%d\t%d\t"
  36. 0040157F  |.  E8 60110000                call    <jmp.&msvcrt.printf>                                       ; |\printf
  37. 00401584  |.  8B4424 18                  mov     eax, dword ptr [esp+0x18]                                  ; |
  38. 00401588  |.  894424 08                  mov     dword ptr [esp+0x8], eax                                   ; |
  39. 0040158C  |.  8B4424 1C                  mov     eax, dword ptr [esp+0x1C]                                  ; |
  40. 00401590  |.  894424 04                  mov     dword ptr [esp+0x4], eax                                   ; |
  41. 00401594  |.  C70424 00404000            mov     dword ptr [esp], 00404000                                  ; |ASCII "%d\t%d\t"
  42. 0040159B  |.  E8 44110000                call    <jmp.&msvcrt.printf>                                       ; \printf
  43. 004015A0  |.  B8 00000000                mov     eax, 0x0
  44. 004015A5  |.  C9                         leave
  45. 004015A6  \.  C3                         retn
  46. ====================================================================================================================================================
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-10-21 21:46:53 | 显示全部楼层
hrpzcf 发表于 2021-10-21 11:35
编译器的原因吧,各编译器实现方法不同,编译结果也不同,所以建议不要用这种写法。

我试了下

感谢帮助
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-10-21 23:16:03 | 显示全部楼层
jackz007 发表于 2021-10-21 11:55
我分别使用 vc6.0 和 gcc 10.2.0 编译了这个源程序,并使用 OllyDBG 仔细跟踪了两个程序的反汇编代 ...

感谢帮助
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-5-11 19:13

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表