鱼C论坛

 找回密码
 立即注册
查看: 1498|回复: 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 的过程二者完全相同。
#include <stdio.h>

void vc(void)
{
        int i = 3 , j = 3 , x , y ;
        x = i + i + i             ;
        i ++                      ;
        i ++                      ;
        i ++                      ;
        j ++                      ;
        j ++                      ;
        y = j + j                 ;
        j ++                      ;
        y += j                    ;
        printf("%d\t%d\t",x,y)    ;
        printf("%d\t%d\n",i,j)    ;
}

void gcc()
{
        int i = 3 , j = 3 , x , y ;
        x = i                     ;
        i ++                      ;
        x += i                    ;
        i ++                      ;
        x += i                    ;
        i ++                      ;
        j ++                      ;
        j ++                      ;
        y = j + j                 ;
        j ++                      ;
        y += j                    ;
        printf("%d\t%d\t",x,y)    ;
        printf("%d\t%d\n",i,j)    ;
}

int main(void)
{
        printf("-------- vc6.0 --------\n") ;
        vc()                                ;
        printf("-------- dev-c --------\n") ;
        gcc()                               ;
}

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

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

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

使用道具 举报

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

我试了下
用gcc编译结果是12 16 6 6
用calng 编译结果是 12 15 6 6,并且有警告。这里的y=15才是预期结果。
PS F:\Repos\ccode> clang main.c -o main.exe
main.c:6:11: warning: multiple unsequenced modifications to 'i' [-Wunsequenced]
    x = (i++) + (i++) + (i++);
          ^       ~~
main.c:7:10: warning: multiple unsequenced modifications to 'j' [-Wunsequenced]
    y = (++j) + (++j) + (++j);
         ^       ~~
2 warnings generated.
PS F:\Repos\ccode> ./main
12      15      6       6
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 的过程二者完全相同。
#include <stdio.h>

void vc(void)
{
        int i = 3 , j = 3 , x , y ;
        x = i + i + i             ;
        i ++                      ;
        i ++                      ;
        i ++                      ;
        j ++                      ;
        j ++                      ;
        y = j + j                 ;
        j ++                      ;
        y += j                    ;
        printf("%d\t%d\t",x,y)    ;
        printf("%d\t%d\n",i,j)    ;
}

void gcc()
{
        int i = 3 , j = 3 , x , y ;
        x = i                     ;
        i ++                      ;
        x += i                    ;
        i ++                      ;
        x += i                    ;
        i ++                      ;
        j ++                      ;
        j ++                      ;
        y = j + j                 ;
        j ++                      ;
        y += j                    ;
        printf("%d\t%d\t",x,y)    ;
        printf("%d\t%d\n",i,j)    ;
}

int main(void)
{
        printf("-------- vc6.0 --------\n") ;
        vc()                                ;
        printf("-------- dev-c --------\n") ;
        gcc()                               ;
}

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

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

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

使用道具 举报

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

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

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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