由++操作引发的问题

来源:互联网 发布:网络寄生虫主机 编辑:程序博客网 时间:2024/05/16 12:17

最近在项目中遇到了一个奇怪的问题,在此作个标记,以免再犯!!
 代码如下:

#include <stdio.h>

int main(int argc, char* argv[])
{
    
int c = 9;
    c 
= c++ % 5;
    printf(
"c = %d ", c);

    
return 0;
}

编译器: sparc-elf-gcc 3.2.3
程序执行结果:c = 10 <从正常的分析来看,结果应该是5>

为什么呢?是不是sparc的编译器对c=c++%5做了其它的理解呢?因此把这段代码反编译得出其汇编代码如下:
编译命令:sparc-elf-gcc -g -o test.exe test.c
                    sparc-elf-objdump -D test.exe > dump.txt

40001174 <main>:
40001174:    9d e3 bf 90     save  %sp, -112%sp
40001178:    f0 27 a0 44     st  %i0, [ %fp + 0x44 ]
4000117c:    f2 
27 a0 48     st  %i1, [ %fp + 0x48 ]
40001180:    90 10 20 09     mov  9%o0
40001184:    d0 27 bf f4     st  %o0, [ %fp + -12 ]
40001188:    c0 27 bf f0     clr  [ %fp + -16 ]
4000118c:    a2 
07 bf f4     add  %fp, -12%l1
40001190:    e0 04 40 00     ld  [ %l1 ], %l0
40001194:    90 10 00 10     mov  %l0, %o0
40001198:    92 10 20 05     mov  5%o1
4000119c:    
40 00 00 13     call  400011e8 <.rem>
400011a0:    
01 00 00 00     nop 
400011a4:    d0 
27 bf f4     st  %o0, [ %fp + -12 ]
400011a8:    a0 
04 20 01     inc  %
l0
400011ac:    e0 
24 40 00     st  %l0, [ %
l1 ]
400011b0:    d0 
07 bf f4     ld  [ %fp + -12 ], %o0
400011b4:    d0 
27 bf f0     st  %o0, [ %fp + -16 ]
400011b8:    
11 10 00 26     sethi  %hi(0x40009800), %o0
400011bc:    
90 12 20 00     mov  %o0, %o0    ! 40009800 <___DTOR_END__>
400011c0:    d2 
07 bf f0     ld  [ %fp + -16 ], %o1
400011c4:    
40 00 00 c7     call  400014e0 <printf>
400011c8:    
01 00 00 00     nop 
400011cc:    
90 10 20 00     clr  %o0    ! 0 <*ABS*>
400011d0:    b0 
10 00 08     mov  %o0, %i0
400011d4:    
01 00 00 00     nop 
400011d8:    
81 c7 e0 08     ret 
400011dc:    
81 e8 00 00     restore 

果然发现了猫腻,sparc-elf-gcc编译器把c的初值(=9)拷贝了两份,分别放在o0和l0中,用o0做了(9%5)的操作,并将值写回到了栈中,然后又用l0中原来存放的值(=9)做自增操作,其结果等于10,并写回到原来的单元中,这样就覆盖了上次的值,所以输出为10。

结果分析:sparc-elf-gcc可能为了节省数据读取的时间,将初值拷贝了两份,导致后用的值没有和sram中同步,这可能是sparc-elf-gcc的一个bug!同样的,这样的程序风格也不值得提倡!~引以为戒

延伸:我用标准gcc或者vc6.0自带的c编译器进行编译的时候是没有问题的!