2

I have this (rather useless) code:

 __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();
    }
 }

I compile that with optimizations on and get this disassembly:

    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

The compiler preserved a foo() function call, but compiled foo() by propagating parameters known at compile time into the function body and optimizing the code. It even emitted

warning C4723: potential divide by 0

Is that expected behavior of Visual C++?

sharptooth
  • 167,383
  • 100
  • 513
  • 979
  • 2
    Umm.... Yes? I'm not really sure what answer you're looking for. – jalf Oct 17 '11 at 07:51
  • Just for reference, this code is used as divide by zero example at: http://stackoverflow.com/questions/7790272/is-dividing-by-zero-accompanied-with-a-runtime-error-ever-useful-in-c/7790459#comment9489633_7790459 – edA-qa mort-ora-y Oct 17 '11 at 08:45
  • smells like LTO/Whole program optimization, which is a specific option of MSVC – Necrolis Oct 17 '11 at 09:15

1 Answers1

3

I guess so. You told it not to inline the function, but you didn't say it couldn't modify the function based on how it is used. It can see that the function is only ever called as foo(0,0), so why shouldn't it optimize the function for that?

try inserting a call to something like foo(1,2) in addition to the (0,0) call and see what happens.

jalf
  • 243,077
  • 51
  • 345
  • 550