• 已解决 73482 个问题
  • 已帮助 5993 位优秀工程师

C语言编译乱序问题

空白12 2018-05-07 浏览量:921
现有如下代码:
int main(int argc char *argv[])
{
int a = 0 b c d[4096] e;
e = d[4095];
b = a;
c = a;
printf("a:%d b:%d c:%d e:%d\n" a b c e);
return 0;
}

用“arm-linux-gnueabihf-gcc-O2”优化编译,反汇编结果是:

int main(int argc char *argv[])
{
831c: b530 push {r4 r5 lr}
831e: f5ad 4d80 sub.w sp sp #16384 ; 0x4000
8322: b083 sub sp #12
8324: 2100 movs r1 #0
8326: f50d 4580 add.w r5 sp #16384 ; 0x4000
832a: f248 4018 movw r0 #33816 ; 0x8418
832e: 3504 adds r5 #4
8330: 460a mov r2 r1 -> b= a;
8332: 460b mov r3 r1 -> c= a;
8334: f2c0 0000 movt r0 #0
8338: 682c ldr r4 [r5 #0]
833a: 9400 str r4 [sp #0] -> e = d[4095];
833c: f7ff efd4 blx 82e8 <_init+0x20>
}

显然,尽管源代码级别b=a、c=a发生在e=d[4095]之后,但是目标代码的b=a、c=a指令发生在e=d[4095]之前。

有人知道是为什么吗?

0 0 收起

我来回答

上传资料:
选择文件 文件大小不超过15M(格式支持:doc、ppt、xls、pdf、zip、rar、txt)
其他答案 数量:2
  • 这个是编译器优化的结果,执行结果相同。想不改变指令顺序要在变量前用volatile 关键字告知编译器不要优化。
    • 发布于2018-05-07
    • 举报
    • 评论 1
    • 0
    • 0
空白12 回复了 apleilx :C语言volatile关键字的作用较弱,它更多的只是避免内存访问行为的合 并,对C编译器而言,volatile是暗示除了当前的执行线索以外,其他的执行线索也可能改变某内存,所以 它的含义是“易变的”。换句话说,就是如果线程A读取var这个内存中的变量两次而没有修改var,编译器 可能觉得读一次就行了,第2次直接取第1次的结果。但是如果加了volatile关键字来形容var,则就是告诉 编译器线程B、线程C或者其他执行实体可能把var改掉了,因此编译器就不会再把线程A代码的第2次内存 读取优化掉了。另外,volatile也不具备保护临界资源的作用。 回复

  • 你的代码应该编译不过的,有语法错误吧?就是示例代码也需要稍微注意一下语法吧。

    此外你的问题应该是编译器自动优化的问题吧。

    • 发布于2018-05-07
    • 举报
    • 评论 1
    • 0
    • 0
空白12 回复了 xdsnet :第一,代码没有错误,我是先在编译之后,才能得到汇编结果的,然后从电脑上直接复制过来的。你说的可能是指定义的时候,少了几个逗号,我这边写的时候没有少,写入帖子里面就少了。第二,这不是编译器自动优化的结果,是我手动指定了O2的优化!现在就是问为什么优化后成样的结果?不要老是答非所问,,水分拿奖么? 回复

相关问题

问题达人换一批

C语言编译乱序问题