[Digital logo]
[HR]

OpenVMS Debugger Manual


Previous | Contents

C.4.3 Data Types

Supported BLISS data types follow:
BLISS Data Type Operating System Data Type Name
BYTE Byte Integer (B)
WORD Word Integer (W)
LONG Longword Integer (L)
QUAD (Alpha specific) Quadword (Q)
BYTE UNSIGNED Byte Unsigned (BU)
WORD UNSIGNED Word Unsigned (WU)
LONG UNSIGNED Longword Unsigned (LU)
QUAD UNSIGNED (Alpha specific) Quadword Unsigned (QU)
VECTOR (None)
BITVECTOR (None)
BLOCK (None)
BLOCKVECTOR (None)
REF VECTOR (None)
REF BITVECTOR (None)
REF BLOCK (None)
REF BLOCKVECTOR (None)

C.5 CC

The following subtopics describe debugger support for C.

C.5.1 Operators in Language Expressions

Supported C operators in language expressions follow:
Kind Symbol Function
Prefix * Indirection
Prefix & Address of
Prefix sizeof size of
Prefix -- Unary minus (negation)
Infix + Addition
Infix -- Subtraction
Infix * Multiplication
Infix / Division
Infix % Remainder
Infix << Left shift
Infix >> Right shift
Infix :=,= Equal to
Infix != Not equal to
Infix > Greater than
Infix >= Greater than or equal to
Infix < Less than
Infix <= Less than or equal to
Prefix ~ (tilde) Bit-wise NOT
Infix & Bit-wise AND
Infix | Bit-wise OR
Infix ^ Bit-wise exclusive OR
Prefix ! Logical NOT
Infix && Logical AND
Infix || Logical OR

Because the exclamation point (!) is an operator in C, it cannot be used as the comment delimiter. When the language is set to C, the debugger instead accepts /* as the comment delimiter. The comment continues to the end of the current line. (A matching */ is neither needed nor recognized.) To permit debugger log files to be used as debugger input, the debugger still recognizes an exclamation point (!) as a comment delimiter if it is the first nonspace character on a line.

The debugger accepts the prefix asterisk (*) as an indirection operator in both C language expressions and debugger address expressions. In address expressions, prefix "*" is synonymous to prefix "." or "@" when the language is set to C.

The debugger does not support any of the assignment operators in C (or any other language) in order to prevent unintended modifications to the program being debugged. Hence such operators as =, +=, --=, ++, and -- are not recognized. To alter the contents of a memory location, you must use an explicit DEPOSIT command.

C.5.2 Constructs in Language and Address Expressions

Supported constructs in language and address expressions for C follow:
Symbol Construct
[ ] Subscripting
. (period) Structure component selection
-> Pointer dereferencing

C.5.3 Data Types

Supported C data types follow:
C Data Type Operating System Data Type Name
__int64 (Alpha specific) Quadword Integer (Q)
unsigned __int64 (Alpha specific) Quadword Unsigned (QU)
__int32 (Alpha specific) Longword Integer (L)
unsigned __int32 (Alpha specific) Longword Unsigned (LU)
int Longword Integer (L)
unsigned int Longword Unsigned (LU)
__int16 (Alpha specific) Word Integer (W)
unsigned __int16 (Alpha specific) Word Unsigned (WU)
short int Word Integer (W)
unsigned short int Word Unsigned (WU)
char Byte Integer (B)
unsigned char Byte Unsigned (BU)
float F_Floating (F)
__f_float (Alpha specific) F_Floating (F)
double D_Floating (D)
double G_Floating (G)
__g_float (Alpha specific) G_Floating (G)
float (Alpha specific) IEEE S_Floating (FS)
__s_float (Alpha specific) IEEE S_Floating (FS)
double (Alpha specific) IEEE T_Floating (FT)
__t_float (Alpha specific) IEEE T_Floating (FT)
enum (None)
struct (None)
union (None)
Pointer Type (None)
Array Type (None)

Floating-point numbers of type float may be represented by F_Floating or IEEE S_Floating, depending on compiler switches.

Floating-point numbers of type double may be represented by IEEE T_Floating, D_Floating, or G_Floating, depending on compiler switches.

C.5.4 Case Sensitivity

Symbol names are case sensitive for language C, meaning that uppercase and lowercase letters are treated as different characters.

C.5.5 Static and Nonstatic Variables

Variables of the following storage classes are allocated statically: static, globaldef, globalref, and extern.

Variables of the following storage classes are allocated nonstatically (on the stack or in registers): auto and register. Such variables can be accessed only when their defining routine is active (on the call stack).

C.5.6 Scalar Variables

You can specify scalar variables of any C type in debugger commands exactly as you would specify them in the source code of the program.

The following paragraphs provide additional information about char variables and pointers.

The char variables are interpreted by the debugger as byte integers, not ASCII characters. To display the contents of a char variable ch as a character, you must use the /ASCII qualifier:

DBG> EXAMINE/ASCII ch
SCALARS\main\ch:      "A"

You also must use the /ASCII qualifier when depositing into a char variable, to translate the byte integer into its ASCII equivalent. For example:

DBG> DEPOSIT/ASCII ch = 'z'
DBG> EXAMINE/ASCII ch
SCALARS\main\ch:        "z"

The following example shows use of pointer syntax with the EXAMINE command. Assume the following declarations and assignments:

static long li  = 790374270; 
static int *ptr = &li; 
DBG> EXAMINE *ptr
*SCALARS\main\ptr:       790374270

C.5.7 Arrays

The debugger handles C arrays as for most other languages. That is, you can examine an entire array aggregate, a slice of an array, or an individual array element, using array syntax (for example EXAMINE arr[3]). And you can deposit into only one array element at a time.

C.5.8 Character Strings

Character strings are implemented in C as null-terminated ASCII strings (ASCIZ strings). To examine and deposit data in an entire string, use the /ASCIZ (or /AZ) qualifier so that the debugger can interpret the end of the string properly. You can examine and deposit individual characters in the string using the C array subscripting operators ([ ]). When you examine and deposit individual characters, use the /ASCII qualifier.

Assume the following declarations and assignments:

static char *s = "vaxie"; 
static char **t = &s; 

The EXAMINE/AZ command displays the contents of the character string pointed to by *s and **t:

DBG> EXAMINE/AZ  *s
*STRING\main\s: "vaxie"
DBG> EXAMINE/AZ  **t
**STRING\main\t:        "vaxie"

The DEPOSIT/AZ command deposits a new ASCIZ string in the variable pointed to by *s. The EXAMINE/AZ command displays the new contents of the string:

DBG> DEPOSIT/AZ  *s = "DEC C"
DBG> EXAMINE/AZ  *s,  **t
*STRING\main\s: "DEC C" 
**STRING\main\t:         "DEC C"

You can use array subscripting to examine individual characters in the string and deposit new ASCII values at specific locations within the string. When accessing individual members of a string, use the /ASCII qualifier. A subsequent EXAMINE/AZ command shows the entire string containing the deposited value:

DBG> EXAMINE/ASCII s[3]
[3]:    " "
DBG> DEPOSIT/ASCII s[3] = "-"
DBG> EXAMINE/AZ *s, **t
*STRING\main\s:    "VAX-C" 
**STRING\main\t:   "VAX-C"

C.5.9 Structures and Unions

You can examine structures in their entirety or on a member-by-member basis, and deposit data into structures one member at a time.

To reference members of a structure or union, use the usual C syntax for such references. That is, if variable p is a pointer to a structure, you can reference member y of that structure with the expression p ->y. If variable x refers to the base of the storage allocated for a structure, you can refer to a member of that structure with the x.y expression.

The debugger uses C type-checking rules to reference members of a structure or union. For example, in the case of x.y, y need not be a member of x; it is treated as an offset with a type. When such a reference is ambiguous---when there is more than one structure with a member y---the debugger attempts to resolve the reference according to the following rules. The same rules for resolving the ambiguity of a reference to a member of a structure or union apply to both x.y and p ->y.

You can always give a path name with the reference to x to narrow the scope that is used and to resolve the ambiguity. The same path name is used to look up both x and y.

C.6 C_PLUS_PLUS

The following subtopics describe debugger support for C++ programs.

C.6.1 The %name Lexical Function

Use of the %name lexical function is required with debugger commands to reference certain entities in DEC C++, such as functions and data members. When used, this function is always placed between the command and the reference. Examples of correct usage are shown in the following sections for cases where its use is required.

C.6.2 Operators in Language Expressions

Supported C++ operators in language expressions follow:
Kind Symbol Function
Prefix * Indirection
Prefix & Address of
Prefix sizeof size of
Prefix -- Unary minus (negation)
Infix + Addition
Infix -- Subtraction
Infix * Multiplication
Infix / Division
Infix % Remainder
Infix << Left shift
Infix >> Right shift
Infix :=,= Equal to
Infix != Not equal to
Infix > Greater than
Infix >= Greater than or equal to
Infix < Less than
Infix <= Less than or equal to
Prefix ~ (tilde) Bit-wise NOT
Infix & Bit-wise AND
Infix | Bit-wise OR
Infix ^ Bit-wise exclusive OR
Prefix ! Logical NOT
Infix && Logical AND
Infix || Logical OR

Because the exclamation point (!) is an operator, it cannot be used in C++ programs as a comment delimiter. However, to permit debugger log files to be used as debugger input, the debugger still recognizes an exclamation point as a comment delimiter if it is the first nonspace character on a line. In C++ language mode, the debugger accepts /* as the comment delimiter. The comment continues to the end of the current line. (A matching */ is neither needed nor recognized.)

The debugger accepts the asterisk (*) prefix as an indirection operator in both C++ language expressions and debugger address expressions. In address expressions, the * prefix is synonymous to the period (.) prefix or at sign @ prefix when the language is set to C++.

To prevent unintended modifications to the program being debugged, the debugger does not support any of the assignment operators in C++ (or any other language). Thus, such operators as =, +=, --=, ++, and -- are not recognized. To alter the contents of a memory location, you must do so with an explicit deposit command.

C.6.3 Constructs in Language and Address Expressions

Supported constructs in language and address expressions for C++ follow:
Symbol Construct
[ ] Subscripting
. (period) Structure component selection
-> Pointer dereferencing

C.6.4 Data Types

Supported C++ data types follow:
C++ Data Type Operating System Data Type Name
__int64 (Alpha specific) Quadword Integer (Q)
unsigned __int64 (Alpha specific) Quadword Unsigned (QU)
__int32 (Alpha specific) Longword Integer (L)
unsigned __int32 (Alpha specific) Longword Unsigned (LU)
int Longword Integer (L)
unsigned int Longword Unsigned (LU)
__int16 (Alpha specific) Word Integer (W)
unsigned __int16 (Alpha specific) Word Unsigned (WU)
short int Word Integer (W)
unsigned short int Word Unsigned (WU)
char Byte Integer (B)
unsigned char Byte Unsigned (BU)
float F_Floating (F)
__f_float (Alpha specific) F_Floating (F)
double D_Floating (D)
double G_Floating (G)
__g_float (Alpha specific) G_Floating (G)
float (Alpha specific) IEEE S_Floating (FS)
__s_float (Alpha specific) IEEE S_Floating (FS)
double (Alpha specific) IEEE T_Floating (FT)
__t_float (Alpha specific) IEEE T_Floating (FT)
enum (None)
struct (None)
union (None)
Pointer Type (None)
Array Type (None)

Floating-point numbers of type float may be represented by F_Floating or IEEE S_Floating, depending on compiler switches.

Floating-point numbers of type double may be represented by IEEE T_Floating, D_Floating, or G_Floating, depending on compiler switches.

C.6.5 Case Sensitivity

Symbol names are case sensitive for C++, meaning that uppercase and lowercase letters are treated as different characters.

C.6.6 Qualified Class Names

Discussions in some of the following sections use the term qualified class names to describe how to compose the names of class members when using the debugger. If a class is not defined within another class, the qualified class name is merely the name of the class itself. However, if a class is nested within another class, the name of the immediately containing class must precede it, separated with a pair of colons (::). If the containing class is itself nested, its name must be prefixed, and so on.

The following are examples of properly qualified class names:

DBG> set break %name 'C::f'             ! f is a member of class C 
DBG> set break %name 'FOO::BAR::BAZ::g' ! g is a member of BAZ, 
                                        ! which is nested in BAR, 
                                        ! which is nested in FOO 

C.6.7 Using the Debugger with C++ Data

This section describes how to use the debugger with C++ data.

C.6.7.1 Nonstatic Data Members

This section describes how to refer to data members that are not declared static.

C.6.7.1.1 Noninherited Data Members

To refer to a nonstatic data member that is defined directly in a C++ class (or a struct or union), use its name just as with a C language struct or union member. The following example shows the correct use of a nonstatic data member reference:

DBG> examine x.m, p->m 

C.6.7.1.2 Inherited Data Members

Currently, debugger support distinguishes nonstatic data members inherited from various base class by prefixing their names with a sequence of significant base class names on the inheritance path to the member, and then the class that the member is declared in. A base class on a path from an object to a member is significant if the base class in question is derived from using multiple inheritance. Thus, a base class is significant if it is mentioned in a base list containing more than one base specifier.

This notation generates the minimum number of base class prefixes necessary to describe the inheritance path to a base class, because it involves naming only those base classes where one must choose where to proceed next when traversing the path. When no multiple inheritance is involved, the reference is of the following form:

%name'CLASS::member' 

To refer to nonstatic data members inherited from base classes of an object, quote the sequence of significant qualified base class names and the member name (separated by double colons) with %name. Specify the sequence of significant base classes, in the order from the object's most derived significant class, to the significant base class closest to the object. For example, consider the inheritance graph for the following declarations:

struct A { int a_member; }; 
struct B : A { int b_member; }; 
struct C { int c_member; }; 
struct D : B, C { int d_member; }; 
struct E : D { int e_member; }; 
struct F { int f_member; }; 
struct G : F { int g_member; }; 
struct H : E, G { int h_member; }; 
struct I : H { int i_member; }; 
struct J : I { int j_member; }; 
 
static J j_object; 

Because classes B, C, E and G are mentioned in base lists, which involve multiple inheritance, they are the significant classes that appear as prefixes. The following examples are references to all the members through debugger deposit commands. Note that the class of the inherited member itself appears before the member name, regardless of whether or not the member belongs to a significant class.

C.6.7.1.3 Inherited Virtual Data Members

In the debugger, symbolic access to data members of virtual base classes is currently not supported. The one exception to this is that the pointer member named __bptr is present in such objects.

C.6.7.2 Static Data Members

To refer to a static data member, quote its qualified class name, two colons (::), and then the member name, with %name.

The following examples show the correct use of static data member references:

DBG> examine %name 'C::s' 
DBG> examine %name 'FOO::BAR::BAZ::sdm' 

C.6.7.3 Reference Objects and Reference Members

To access the values of objects declared with a reference, use the name of the object.

The debugger treats data members declared with a reference type as though they were pointer variables; thus, you must use the * or -> dereference operators on their names. For example, consider the following code:

class C { 
public: 
    int &ref_mem; 
    C(int &arg) : ref_mem(arg) {} 
}; 
 
main() 
{ 
    auto int obj = 5; 
    auto int &ref_obj = obj; 
    auto C c(obj); 
    obj = 23; 
} 
   .
   .
   .

The following sequence shows the correct way to use the debugger to examine the members:

stepped on return from routine REF\main 
  to REF\main\%LINE 13+16 
    13: } 
DBG> examine obj, ref_obj 
REF\main\obj:   23 
REF\main\ref_obj:       23 
DBG> examine c 
REF\main\c 
    ref_mem:    2144211292 
DBG> symbolize c.ref_mem 
address 7FCE1154: 
    REF\main\c 
DBG> examine *c.ref_mem 
*REF\main\c.ref_mem:    23 

C.6.7.4 Pointers to Members

Objects that are pointers to members are represented as 64-bit integers.

C.6.7.5 Referencing Entities by Type

To examine and display the value of an object or member by type, use the command EXAMINE/TYPE. Similarly, you can modify the value of an expression to be deposited to a type you specify by using the DEPOSIT/TYPE command. With the /TYPE qualifier, the syntax for these commands is as follows:

deposit/type=(name) 
examine/type=(name) 

The type denoted by name must be the name of a variable or data type declared in the program. The /type qualifier is particularly useful for referencing C++ objects that have been declared with more than one type.

C.6.8 Using the Debugger with C++ Functions

This section describes how to reference the various kinds of functions and function arguments.

C.6.8.1 Referring to Overloaded Functions

To find the symbolic names of functions in your code, use the SHOW SYMBOL command. If the function is overloaded, use the asterisk wildcard character (*) in the name specification to display the overloaded symbol names.


Previous | Next | Contents | [Home] | [Comments] | [Ordering info] | [Help]

[HR]

  4538P054.HTM
  OSSG Documentation
  22-NOV-1996 13:02:56.67

Copyright © Digital Equipment Corporation 1996. All Rights Reserved.

Legal