Reliable Software Logo

C++ In Action: Language

Debugging

Wouldn't it be nice to have a tool that would show you, step by step, how your program is executing? Luckily, such tools exist and are called debuggers. There are many implementations of debuggers, but they all offer the same basic functionality. There is a debugger built into Microsoft Developer's Studio a.k.a. Visual C++, so I'll use it as an example.

Once you have your program built, you step into it. In VC++ you do it by pressing F11. What happens next is that your program starts executing, but it is stopped immediately after entering main. You have just stepped into main. You can continue stepping through your program, line by line, by pressing the step over button. When you are positioned at a method call, stepping over will execute the method and position you right after the call. If, on the other hand, you'd like to follow the execution of this method, you should press the step into button. The debugger will jump into the method that's being called and show it to you.

All through the debugging session you'll have additional panes showing the state of the program (if you don't have these panes, go to the View menu and select Debug Windows). One pane shows the values of all the local variables in the current scope. Another pane shows the call stack, or who called whom, called whom... The top of the call stack shows the place where you are currently stopped.

The great thing about the call stack is that you can double-click on any of the callers and the debugger will show you where in the calling method the call was made. At the same time, the local-variable window will be updated to show the values of local variables of this particular caller.

Look at the screen shot below. I first stepped into main by pressing F11. Then I did a few step-overs to get to the line in main that calls num.AddInput(). (Incidentally, when stepping over input statements, you have to go to your application window and actually type in the numbers before you can continue stepping.) Instead of stepping over this call, I chose to step into AddInput. I continued stepping over until I got to the line that calls aNum.GetValue() at which point I stepped into GetValue(). You can see where I stopped inside GetValue()--there's an arrow pointing at the appropriate line.

Then I double clicked on InputNum::AddInput() in the call stack in order to see the values of local variables at the time GetValue() was called. You can see the second (triangular) arrow pointing at the very point where the call was made. The variable window was updated appropriately, showing the values of aNum and this. "This" is the current object--the object in whose context the call was made. Notice that, since the variables here are objects of the class InputNum, you can expand them to see the values of their member variables. In this case, you see the values of _num for both, aNum and this. They are, respectively, 11 and 5. (Your debugger might display them in hexadecimal notation as 0xb and 0x5.)

Debug Window

Click this image to see it full size