• Aucun résultat trouvé

Evaluating and modifying

Dans le document Turbo Pasca~ (Page 150-155)

Table 5.1. See "Modification issues" on page 140 for information on how to modify Watch expressions.

It's easy to edit, add, or delete watches. When the Watch window is active, the currently active expression is highlighted. To select a different expression, use the Home, End,

i ,

or J, keys.

To edit (change) the currently highlighted watch, you can choose Debug I Watches I Edit Watch. Even easier, as shown on the bottom line of the screen, you can press Enter. The debugger opens a pop-up window with the selected expression, and you can edit it.

You already know how to add watches, but once the Watch window is active, there's an easier way: Press Ins. A pop-up window appears. You can type in the watch expression, add to it with the ~ key, or accept the default that was copied from the cursor position.

To delete the current watch, choose Debug I Watches I Delete Watch, or simply press Del. You can delete all of the watches by choosing Debug I Watches I Remove All Watches.

The Watch window is wonderful for tracing values as you step through your program. Other times, you may want to

interactively check a variable or change its value without creating a watch point.

To accommodate these needs, the debugger offers the Evaluate and Modify window. To bring it up, choose the Debug I Evaluate/Modify command (or press Ctrl-F4). This window contains the Expression, Result, and New value boxes.

As with the Add watch box, the Evaluate and Modify box already contains the word found at the cursor; it's in highlight mode. Edit it as you would the Add Watch box and press Enter when you want to evaluate it. The current value of the constant, variable, or expression will then appear in the Result box.

The Evaluate box accepts exactly the same set of constants,

variables, and expressions that the Watch window does. You have the same freedoms and restrictions we've already mentioned. You can also use the same format characters as you can for Watch expressions.

When you press Enter, the identifier or expression in the Evaluate box is highlighted again, which means if you start typing a new name (without pressing Ins or an arrow key), it will replace the old one. This lets you quickly type in a series of variables and expressions.

The New Value box allows you to modify the value of the variables named in the Evaluate box. You can enter a constant value, the name of another variable, or even an expression. The resulting value must be of a type compatible with the variable in the Evaluate box. Therefore, if you have an expression in Evaluate that does not result in a memory location, then any value entered in New Va~ue will result in the message "Cannot be modified."

The Result box shows the current value of whatever is in the Evaluate box, using the same format as the Watch window. And, like the Watch window, the data will sometimes be too large to fit.

In such cases, you can use the Tab, Backtab, ~ , -7 , Home, and End keys to scroll through the box.

In all cases, you can use the

t

and J, keys (or regular keyboard editing commands) to move between the three boxes. Once you have modified a box, press Enter to evaluate the input.

Modifying expressions The ability to modify a variable while the program is running is a tremendous help while debugging. It can also be dangerous, so you need to be sure you know the do·'s and don'ts of modification.

The simplest form of modification is to enter a variable name in the Evaluate box and a corresponding value in the New Value box. When you press Enter after typing in the new value, the variable's value is changed, and the Result box is updated to reflect that.

You are not limited to constant values, though. You can enter into the New Value box any variable or expression that you could enter into the Evaluate box, with one major qualification: It must be assignment-compatible with the variable or expression in the Evaluate box. In other words, if exprl represents what's currently in the Evaluate box, then you cannot legally enter the expression expr2 into the New Value box if the statement

exprl := expr2i

would cause a compiler or run-time error.

Note that the reverse is not necessarily true: There are cases when the statement

exprl := expr2;

is legal, but you still cannot use expr2 in the New Value box.

If the expression entered is an incompatible type-such as entering a floating-point value for an integer variable-then the Result box will instead display the message "Type mismatch." To make the Result box redisplay the current value of the variable, move back up to the Evaluate box and press Enter.

If the expression entered yields an out-of-range value-such as entering 50,000 for a variable of type Integer-the Result box will display the message "Constant out of range." The same thing will occur if you type in an array element with an index that's out of range.

If the expression entered in the New Value box is one that can't be assigned, then the Result box will get the message "Cannot evaluate this expression." Such expressions include arrays, records, sets, and files.

Likewise, if the variable or expression in the Evaluate box is one that can't be modified-a whole array, record, set, or a file-then attempting to assign a value to it will produce the message

"Cannot be modified."

What can you modify? Refer to Table 5.1 on page 138 for a list of what can be used in a Watch expression, along with acceptable values. Remember, though, that expressions can only use the built-in functions listed as acceptable for Watch expressions in Table 5.1.

Other things to keep in mind:

• You can't modify entire arrays, entire records, or files; however, as mentioned, you can modify individual elements of arrays or records that resolve to one of the types listed in Table 5.1, provided they are not themselves arrays or records.

• You can't directly modify untyped parameters passed into a procedure or function. You can, however, typecast them to a given type, then modify them according to the restrictions we've just detailed.

• Be aware that there can be some real dangers in modifying variables. For example, if you change a pointer, you could end

Navigation

up making changes to memory that you didn't mean to, possibly even modifying other variables and data structures.

When you are debugging a large program, especially one spread out over several units, you can actually get lost, or at least buried so deep that you can't figure out how best to get to where you want to go. To aid you with navigation, the debugger provides two mechanisms: the Window I Call Stack and Search I Find Procedure commands.

The call stack Each time a procedure or function is called, Turbo Pascal remembers the call and the parameters passed to it by pushing the information on the call stack. When you exit that procedure or function, then the call is popped off the stack, returning execution to the calling routine.

Whenever your program pausesbecause of a breakpoint or a single-step command, you can ask to see the current call stack by using the Window I Call Stack command (Ctrl-F3). This displays a window that shows the list of procedure/ function calls currently active on the stack.

The call stack allows you to look back through the sequence of calls. When you first bring up the call stack, the topmost call is highlighted. You can use the arrow keys to move up and down through the stack. If you press Spacebar, you will be taken to the last active point within that program. Consider the following small program (TESTPOWER.P AS):

program TestPower;

function Power(Base,Exp: Word): Longint;

begin

if Exp <= 0 then Power := 1 else

Power := Base * Power (Base,Exp-l) ';

end; { of func Power }

begin { main body of TestPower } Writeln('2A14

= ,

,Power(2,14));

end. { of program TestPower } A eGA will display 9 calls; a

Hercules, EGA, or VGA will display 72.

Compile TESTPOWER, and set a breakpoint on the second line of the function Power (the line Power := 1). Now run the program.

Finding procedures and functions

When it pauses, choose the Window I Call Stack command. You can use the

i

and'!' keys to move through the calls. The call stack tracks up to 128 nested calls.

Sometimes, in the middle of debugging, you want to find a particular procedure or function in order to set a breakpoint, execute to that point, check the parameter list, look at the variables, or any number of other reasons.

If your source code is spread out among multiple files, you'll love the Search I Find Procedure command. This command leads you to a small window, where you can enter the name of a procedure or function. After you type in an identifier and press Enter, Turbo Pascal checks its internal tables to find where that subprogram is located, loads in the appropriate source file (if necessary), and puts you in the Edit window with the cursor positioned at the beginning of the procedure or function.

There are three important things to remember about using the Search I Find Procedure command:

• Find Procedure does not affect your current debugging state. In other words, if you're paused at some point in your program, you are still paused there, and choosing Run I Trace Into (F7)

will execute that line in your program, not the procedure or function you've just located.

• Find Procedure places the cursor at the first executable line of that procedure or function, rather than on the procedure or function header. This means you can choose Run I Go to Cursor

(F4) to execute from your current position to the start of that procedure or function.

• You can only use this command if you have compiled your program and debug information is available for the procedure or function.

Since you may have routines with the same name in several different places in your program (in units, nested inside of other routines, and so on), it's a good idea to qualify the routine's name by preceding it with the name of the unit or program containing it, as well as any procedures or functions that might enclose it; for example, module.proc.proc.<etc.>.proc. If you modify the source code and the file position (or even name) of a procedure or function is changed, the Search I Find Procedure command won't know about any of those changes until you recompile. If you first compile program TestPower (see the section on "The call stack,"

page 142) and then delete the blank line above the declaration of function Power, Search I Find Procedure will put the cursor on the if ... then instead of the begin.

Dans le document Turbo Pasca~ (Page 150-155)