我有这个(相当无用)代码:
__declspec(noinline)
int foo( char* ptr, int offset )
{
if( 5 / offset == 3 ) {
return 1;
}
if( ptr != ptr + offset ) {
return 2;
}
return 0;
}
int _tmain(int /*argc*/, _TCHAR* /*argv*/[])
{
if( foo( 0, 0 ) ) {
rand();
}
}
我在优化的情况下编译它并得到这个反汇编:
141: __declspec(noinline)
142: int foo( char* ptr, int offset )
143: {
144: if( 5 / offset == 3 ) {
00401000 push 5
00401002 pop eax
00401003 cdq
00401004 xor ecx,ecx
00401006 idiv eax,ecx
00401008 sub eax,3
0040100B neg eax
0040100D sbb eax,eax
0040100F inc eax
145: return 1;
146: }
147: if( ptr != ptr + offset ) {
148: return 2;
149: }
150: return 0;
151: }
00401010 ret
152:
153: int _tmain(int /*argc*/, _TCHAR* /*argv*/[])
154: {
155: if( foo( 0, 0 ) ) {
00401011 call foo (401000h)
00401016 test eax,eax
00401018 je wmain+0Fh (401020h)
156: rand();
0040101A call dword ptr [__imp__rand (4020A0h)]
157: }
158: }
00401020 xor eax,eax
00401022 ret
编译器保留了 foo()
函数调用,但通过将编译时已知的参数传播到函数体并优化代码来编译 foo()
。它甚至发出了
warning C4723: potential divide by 0
这是 Visual C++ 的预期行为吗?
最佳答案
我想是的。您告诉它不要内联该函数,但没有说它不能根据函数的使用方式修改该函数。它可以看到该函数仅被调用为 foo(0,0)
,那么为什么不应该为此优化该函数呢?
除了 (0,0)
调用之外,尝试插入对诸如 foo(1,2)
之类的调用,看看会发生什么。
关于c++ - Visual C++ 的这种奇怪的内联行为是否符合预期?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7790687/