HP OpenVMS Systems Documentation
HP OpenVMS Debugger Manual
18.104.22.168 Using Variables in Language Expressions
You can use variables in language expressions in much the same way that you use them in the source code of your program.
Thus, the debugger generally interprets a variable used in a language expression as the current value of that variable, not the address of the variable. For example (X is an integer variable):
Using a variable in a language expression as shown in the previous examples is generally limited to single-valued, noncomposite variables. Typically, you can specify a multivalued, composite variable (like an array or record) in a language expression only if the syntax indicates that you are referencing only a single value (a single element of the aggregate). For example, if ARR is the name of an array of integers, the following command is invalid:
However, the following commands are valid because only a single element of the array is referenced:
If the current language is BLISS, the debugger interprets a variable in a language expression as the address of that variable. To denote the value stored in a variable, you must use the contents-of operator (period (.)). For example, when the language is set to BLISS:
For all languages, to obtain the address of a variable, use the
When evaluating language expressions involving numeric types of different precision, the debugger first converts lower-precision types to higher-precision types before performing the evaluation. In the following example, the debugger converts the integer 1 to the real 1.0 before doing the addition:
The basic rules are as follows:
In general, the debugger allows more numeric type conversion than the
programming language. In addition, the hardware type used for a
debugger calculation (word, longword, S_float, and so on) might differ
from that chosen by the compiler. Because the debugger is not as
strongly typed or as precise as some languages, the evaluation of an
expression by the EVALUATE command might differ from the result that
would be calculated by compiler-generated code and obtained with the
Do not confuse address expressions with language expressions. An address expression specifies a program location; a language expression specifies a value. In particular, the EXAMINE command expects an address expression as its parameter, and the EVALUATE command expects a language expression as its parameter. These points are shown in the next examples.
In the following example, the value 12 is deposited into the variable X. This is confirmed by the EXAMINE command. The EVALUATE command computes and displays the sum of the current value of X and the integer literal 6,
In the next example, the EXAMINE command displays the value currently stored at the memory location that is 6 bytes beyond the address of X:
In this case the location is not associated with a compiler-generated type. Therefore, the debugger interprets and displays the value stored at that location in the type longword integer (see Section 4.1.5).
In the next example, the value of X + 6 (that is, 18) is deposited into the location that is 6 bytes beyond the address of X. This is confirmed by the last EXAMINE command.
4.1.8 Specifying the Current, Previous, and Next Entity
When using the EXAMINE and DEPOSIT commands, you can use three special built-in symbols (address expressions) to refer quickly to the current, previous, and next data locations (logical entities). These are the period (.), the circumflex (^), and the Return key.
The period (.), when used by itself with an EXAMINE or DEPOSIT command, denotes the current entity---that is, the program location most recently referenced by an EXAMINE or DEPOSIT command. For example:
The circumflex (^) and Return key denote, respectively, the previous and next logical data locations relative to the last EXAMINE or DEPOSIT command (the logical predecessor and successor, respectively). The circumflex and Return key are useful for referring to consecutive indexed components of an array. The following example shows the use of these operators with an array of integers, ARR:
The debugger uses the type associated with the current entity to determine logical successors and predecessors.
You can also use the built-in symbols %CURLOC, %PREVLOC, and %NEXTLOC to achieve the same purpose as the period, circumflex, and Return key, respectively. These symbols are useful in command procedures and also if your program uses the circumflex for other purposes. Moreover, using the Return key to signify the logical successor does not apply to all contexts. For example, you cannot press the Return key after entering the DEPOSIT command to indicate the next location, but you can always use the symbol %NEXTLOC for that purpose.
Note that, like EXAMINE and DEPOSIT, the EVALUATE/ADDRESS command also resets the values of the current, previous, and next logical-entity built-in symbols (see Section 4.1.11). However, you cannot press the Return key after entering the EVALUATE/ADDRESS command to indicate the next location. For more information about debugger built-in symbols, see Appendix B.
The previous examples show the use of the built-in symbols after referencing a symbolic name with the EXAMINE or DEPOSIT command. If you examine or deposit into a memory address, that location might or might not be associated with a compiler-generated type. When you reference a memory address, the debugger uses the following conventions to determine logical predecessors and successors:
As the current entity is reset with new examine or deposit operations, the debugger associates each new location with a type in the manner indicated to determine logical successors and predecessors. This is shown in the following examples.
Assume that a Fortran program has declared three variables, ARY, FLT, and BTE, as follows:
Assume that storage for these variables has been allocated at consecutive addresses in memory, starting with 1000. For example:
Examining successive logical data locations will give the following results:
The same principles apply when you use type qualifiers with the EXAMINE
and DEPOSIT commands (see Section 4.5.2). The type specified by the
qualifier determines the data boundary of an entity and, therefore, any
logical successors and predecessors.
The debugger enables you to set your debugging context to any of several supported languages. The setting of the current language determines how the debugger parses and interprets the names, numbers, operators, and expressions you specify in debugger commands, and how it displays data.
By default, the current language is the language of the module containing the main program, and it is identified when you bring the program under debugger control. For example:
When debugging modules whose code is written in other languages, you
can use the SET LANGUAGE command to establish a new language-dependent
context. Section 14.3 highlights some important language differences.
Debugger support for operators and other constructs in language
expressions is listed for each language in the debugger's online help
(type HELP Language).
The debugger can interpret and display integer data in any one of four radixes: decimal, hexadecimal, octal, and binary. The default radix is decimal for most languages.
On VAX processors, the exceptions are BLISS and MACRO--32, which have a default radix of hexadecimal.
On Alpha processors, the exceptions are BLISS, MACRO--32 and MACRO--64, which have a default radix of hexadecimal.
You can control the radix for the following kinds of integer data:
You cannot control the radix for other kinds of integer data. For example, addresses are always displayed in hexadecimal radix in a SHOW CALLS display. Or, when specifying an integer n with various command qualifiers (/AFTER:n, /UP:n, and so on), you must use decimal radix.
The technique you use to control radix depends on your objective. To establish a new radix for all subsequent commands, use the SET RADIX command. For example:
After this command is executed, all integer data that you enter in address or language expressions is interpreted as being hexadecimal. Also, all integer data displayed by the EVALUATE and EXAMINE commands is given in hexadecimal radix.
The SHOW RADIX command identifies the current radix (which is either the default radix, or the radix last established by a SET RADIX command). For example:
The SHOW RADIX command identifies both the input radix (for data entry) and the output radix (for data display). The SET RADIX command qualifiers /INPUT and /OUTPUT enable you to specify different radixes for data entry and display. For more information, see the SET RADIX command.
Use the CANCEL RADIX command to restore the default radix.
The examples that follow show several techniques for displaying or entering integer data in another radix without changing the current radix.
The radix qualifiers do not affect the radix for data entry.
To display the current value of an integer variable (or the contents of a program location that has an integer type) in another radix, use the EXAMINE command with a radix qualifier. For example:
To enter one or more integer literals in another radix without changing the current radix, use one of the radix built-in symbols %BIN, %DEC, %HEX, or %OCT. A radix built-in symbol directs the debugger to treat an integer literal that follows (or all numeric literals in a parenthesized expression that follows) as a binary, decimal, hexadecimal, or octal number, respectively. These symbols do not affect the radix for data display. For example:
Use the EVALUATE/ADDRESS command to determine the memory address or the register name associated with a symbolic address expression, such as a variable name, line number, routine name, or label. For example:
The address is displayed in the current radix (as defined in Section 4.1.10). You can specify a radix qualifier to display the address in another radix. For example:
If a variable is associated with a register instead of a memory address, the EVALUATE/ADDRESS command displays the name of the register, regardless of whether a radix qualifier is used. The following command indicates that variable K (a nonstatic variable) is associated with register R2:
Like the EXAMINE and DEPOSIT commands, EVALUATE/ADDRESS resets the values of the current, previous, and next logical-entity built-in symbols (see Section 4.1.8). Unlike the EVALUATE command, EVALUATE/ADDRESS does not affect the current-value built-in symbols %CURVAL and backslash (\).
The SYMBOLIZE command does the reverse of EVALUATE/ADDRESS, but without affecting the current, previous, or next logical-entity built-in symbols. It converts a memory address or a register name into its symbolic representation (including its path name) if such a representation is possible (Chapter 5 explains how to control symbolization). For example, the following command shows that variable K is associated with register R2:
By default, symbolic mode is in effect (SET MODE SYMBOLIC). Therefore, the debugger displays all addresses symbolically if symbols are available for the addresses. For example, if you specify a numeric address with the EXAMINE command, the address is displayed in symbolic form if symbolic information is available:
However, if you specify a register that is associated with a variable, the EXAMINE command does not convert the register name to the variable name. For example:
By entering the SET MODE NOSYMBOLIC command, you disable symbolic mode and cause the debugger to display numeric addresses rather than their symbolic names. When symbolization is disabled, the debugger might process commands somewhat faster because it does not need to convert numbers to names. The EXAMINE command has a /[NO]SYMBOLIC qualifier that enables you to control symbolization for a single EXAMINE command. For example:
Symbolic mode also affects the display of instructions.
For example, on VAX processors:
4.2 Examining and Depositing into Variables
The examples in this section show how to use the EXAMINE and DEPOSIT commands with variables.
Languages differ in the types of variables they use, the names for these types, and the degree to which different types can be intermixed in expressions. The following generic types are discussed in this section:
The most important consideration when examining and manipulating variables in high-level language programs is that the debugger recognizes the names, syntax, type constraints, and scoping rules of the variables in your program. Therefore, when specifying a variable with the EXAMINE or DEPOSIT command, you use the same syntax that is used in the source code. The debugger processes and displays the data accordingly. Similarly, when assigning a value to a variable, the debugger follows the typing rules of the language. It issues a diagnostic message if you try to deposit an incompatible value. The examples in this section show some of these invalid operations and the resulting diagnostics.
When using the DEPOSIT command (or any other command), note the following behavior. If the debugger issues a diagnostic message with a severity level of I (informational), the command is still executed (the deposit is made in this case). The debugger aborts an illegal command line only when the severity level of the message is W (warning) or greater.