Feb 8, 2012

What's wrong with this code - fun with assembly

Since, I'm a bit busy to create new posts I decided to cheat, translating this post from my old (Portuguese) blog :)

Before we continue let me make this clear: finding the actual issue is not terrible hard (even though it took me some time and of course I'll keep the answer to a future post :); the interesting part is to figure it out why it works (or at least, why it works when compiled with some compilers).


Ok, so lets go. Take a look in the following program: 


This program accepts a number (command line) and calculates its factorial.

I came across it while I was corrigindo a programming assignment from one of my students (yep, 14 years ago I used to work as a professor teaching C, C++, assembly and the like).

At that time I used Borland C++ 3.0 to compile and to my astonishment it worked! Last time, when I tried to compile it with VC 6 I noticed a different behavior (the application produced a wrong result) but using Visual Studio 2010 I can reproduce the same behavior as when I first compiled it with Borland C++ 3.0; of course, the compiler generated some warnings which were promptly ignored!


Warning
To ignore compiler warnings is not such a smart idea and of course I'm not recommending you should do it!

Pelo contrário; check all compiler 
warnings in your code and understand the reasons leading the compiler to complain.Do not assume that the compiler has bugs (after all, Select is not broken). If the conclusion is that the code generating the warning is legitimate I suggest you to try to change it, or, in the worst case, disable the specific warning (via #pragma warning) just in the parts of the code that is producing the warning.

int fat(int n)
{
    if (n == 1)
        return 1;
    else
        n = n * fat(n - 1);
}

int main(int argc, char *argv[])
{
     int n = argc > 1 ? atoi(argv[1]) : 5;
     int i = fat(n);
   
     return printf("Fat(%d): %d", n, i);
 }


Have you figured it out already?


See you!