【发布时间】:2011-11-13 09:36:59
【问题描述】:
对于赏金:如何在不禁用或降低优化级别的情况下根据具体情况禁用此行为?
以下条件表达式是在 MinGW GCC 3.4.5 上编译的,其中 a 是 signed long 类型,m 是 unsigned long 类型。
if (!a && m > 0x002 && m < 0x111)
使用的CFLAGS 是-g -O2。这是对应的汇编GCC输出(用objdump转储)
120: 8b 5d d0 mov ebx,DWORD PTR [ebp-0x30]
123: 85 db test ebx,ebx
125: 0f 94 c0 sete al
128: 31 d2 xor edx,edx
12a: 83 7d d4 02 cmp DWORD PTR [ebp-0x2c],0x2
12e: 0f 97 c2 seta dl
131: 85 c2 test edx,eax
133: 0f 84 1e 01 00 00 je 257 <_MyFunction+0x227>
139: 81 7d d4 10 01 00 00 cmp DWORD PTR [ebp-0x2c],0x110
140: 0f 87 11 01 00 00 ja 257 <_MyFunction+0x227>
120-131 可以很容易地追踪为首先评估!a,然后评估m > 0x002。第一次跳转条件直到133 才会发生。此时,已经评估了 两个 表达式,无论第一个表达式的结果如何:!a。如果a 等于0,则表达式可以(并且应该)立即结束,这里不做。
这与要求布尔运算符在确定结果后立即短路的 C 标准有何关系?
【问题讨论】:
-
可能是因为编译器知道比较 POD 没有副作用?这是在打开还是关闭优化的情况下编译的?
-
我在帖子中给出了编译选项:
-g -O2。所以是的,通过优化。 -
@RedX:这是 C,不是 C++。 “POD”未定义,所有比较都没有副作用(尽管对其操作数的评估可能有副作用,在这种情况下无法进行此类优化)。
-
如果操作数之一是函数调用并且函数具有副作用,则比较不是无副作用的。在这种情况下,短路可能变得很重要。在上面的代码中,它不是。
-
@RudyVelthuis:R. 已经提到:“(尽管对其操作数的评估可能有副作用......)”。
标签: c gcc compiler-construction mingw compiler-optimization