简单分析针对ARM平台的C语言程序的编译问题
我们知道在C语言编译时,有那么几个常用的优化编译选项,分别是-O0,-O1,-O2,-O3以及-Os。之前一直觉得既然是优化选项,顶多是优化一下逻辑,提高一些效率或者减少一下程序大小而已。很少会觉得它们会影响程序的最终结果。直到最近在ARM平台上发现一个程序里的一个bug,才觉得这些优化选项有时候也没那么智能。或者说针对ARM平台,还没有那么智能。 #include<stdio.h> #include<string.h> int main() { char buffer[1024] = {0,1,2,3,4,5,6,7}; int iTest = 0x12345678; int *p = (int *)(buffer + 7); memcpy(p,&iTest,sizeof(iTest)); printf("%xn",buffer[6]); printf("%xn",buffer[9]); return 0; } 乍看之下,觉得这个程序没啥问题。然后我们将此程序文件名称叫point.c。然后分别用交叉编译链进行如下编译: arm-xxx-linux-gcc point.c -o point0 -O0 arm-xxx-linux-gcc point.c -o point1 -O1 arm-xxx-linux-gcc point.c -o point2 -O2 最终再分别执行三个程序,结果却有点出人意料: ./point0 6 34 ./point1 34 0 ./point2 6 0 只有在-O0,也就是没有优化的情况下,结果才和假想的一致。但是同样的问题在x86平台上却没有问题。 arm-xxx-linux-gcc point.c -o point0.s -O0 -S arm-xxx-linux-gcc point.c -o point1.s -O1 -S arm-xxx-linux-gcc point.c -o point2.s -O2 -S 然后对比三个汇编的代码,发现问题出在memcpy这句话上。 #include<stdio.h> #include<string.h> int main() { char buffer[1024] = {0,7}; int iTest = 0x12345678; char *p = buffer + 7; memcpy(p,buffer[9]); return 0; } 这段程序其实只是简单的改变了p的类型,就能保证在各种优化下,结果都一样。可见好的编程习惯是有多么的重要。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |