由++操作引发的问题
来源:互联网 发布:网络寄生虫主机 编辑:程序博客网 时间: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;
}
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
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编译器进行编译的时候是没有问题的!
- 由++操作引发的问题
- 由Typedef引发的问题
- 由UseSubmitBehavior引发的问题
- 由static引发的问题
- 由引用引发的问题
- 由LaunchMode引发的问题
- 由const引发的版本控制问题
- 由一个问题引发的思考
- 由py2exe引发的问题及解决方案
- 由object不能比较引发的问题
- 由 EditorBrowableAttribute 引发的一些问题
- Spinner(1): 由SDK引发的问题
- 由py2exe引发的问题及解决方案
- 由n阶幻方问题引发的思考
- 由webdings引发的乱码问题
- C/C++ 由fopen_s引发的问题
- 由jboss引发的 source level 问题
- 由localtime引发的函数可重入问题
- 博客开通了---兴奋ing
- VC++ 6.0的小花招
- java
- 博客开通了---兴奋ing
- Image2Pdf使用心得
- 由++操作引发的问题
- SCWCD也过啦(附备考资料下载)
- 实现数据随机排序
- MySQL语法语句速成
- 呵呵~
- C++内存管理变革
- 数据库访问通用类(封装)示例2
- 日记(11/16)
- 我的脚步该迈向哪里.......