Document revision date: 30 March 2001

## OpenVMS Debugger Manual

Previous | Contents | Index

### 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` .

- If only one of the members, `y` , belongs in the structure or union, `x` , that is the one that is referenced.
- If only one of the members, `y` , is in the same scope as `x` , then that is the one that is referenced.

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++ Version 5.5 and Later (Alpha Only)

On Alpha systems, the OpenVMS debugger provides enhanced support for debugging C++ modules compiled with the Version 5.5 compiler or later (Alpha only).

The debugger supports the following C++ features:

- C++ names and expressions, including:
  - Explicit and implicit this pointer to refer to class members
  - Scope resolution operator (::)
  - Member access operators: period (.) and right arrow (->)
  - Template instantiations
- Setting breakpoints in:
  - Member functions, including static and virtual functions
  - Overloaded functions
  - Constructors and destructors
  - Template instantiations
  - Operators
- Calling functions, including overloaded functions
- Debugging programs containing a mixture of C++ code and code in other languages

The debugging examples in this section refer to the test program contained in Example C-1, and are extracted from the debugging session contained in Example C-2. The following subtopics describe debugger support for C++ (Compiler Version 5.5 (Alpha only)).

### C.6.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, 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 interprets ! as a comment delimiter when it is the first nonspace character on a line. In C++ language mode, the debugger also interprets /* or // as preceding a comment that continues to the end of the current line.

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 with either the period (.) prefix or at sign (@) prefix when the debugger is in C++ language mode.

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 in debugger commands. To alter the contents of a memory location, you must use the debugger DEPOSIT command.

### C.6.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
:: | Scope resolution

### C.6.3 Data Types

Supported C++ data types follow:

C++ Data Type | Operating System Data Type Name
--- | ---
__int64 (Alpha) | Quadword Integer (Q)
unsigned __int64 (Alpha) | Quadword Unsigned (QU)
__int32 (Alpha) | Longword Integer (L)
unsigned __int32 (Alpha) | Longword Unsigned (LU)
int | Longword Integer (L)
unsigned int | Longword Unsigned (LU)
__int16 (Alpha) | Word Integer (W)
unsigned __int16 (Alpha) | 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) | F_Floating (F)
double | D_Floating (D)
double | G_Floating (G)
__g_float (Alpha) | G_Floating (G)
float (Alpha) | IEEE S_Floating (FS)
__s_float (Alpha) | IEEE S_Floating (FS)
double (Alpha) | IEEE T_Floating (FT)
__t_float (Alpha) | IEEE T_Floating (FT)
enum | (None)
struct | (None)
class | (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.4 Case Sensitivity

Symbol names are case sensitive in C++. This means that uppercase and lowercase letters are treated as different characters.

### C.6.5 Displaying Information About a Class

Use the command SHOW SYMBOL to display static information about a class declaration. Use the command EXAMINE to view dynamic information about class objects (see Section C.6.6).

The command SHOW SYMBOL/FULL displays the class type declaration, including:

> Data members (including static data members)
> Member functions (including static member functions)
> Constructors and destructors
> Base classes and derived classes

For example:

    dbg> SHOW SYMBOL /TYPE C
    type C
        struct (C, 13 components), size: 40 bytes
    overloaded name C
           instance C::C(void)
           instance C::C(const C &)
    dbg> SHOW SYMBOL /FULL C
    type C
        struct (C, 13 components), size: 40 bytes
          inherits: B1, size: 24 bytes, offset: 0 bytes
                    B2, size: 24 bytes, offset: 12 bytes
          contains the following members:
            overloaded name C::g
                   instance C::g(int)
                   instance C::g(long)
                   instance C::g(char)
            j : longword integer, size: 4 bytes, offset: 24 bytes
            s : longword integer, size: 4 bytes, address: #  [static]
            overloaded name C
            int ==(C &)
            C & =(const C &)
            void h(void)   [virtual]
            ~C(void)
            __vptr : typed pointer type, size: 4 bytes, offset: 4 bytes
            __bptr : typed pointer type, size: 4 bytes, offset: 8 bytes
            structure has been padded, size: 4 bytes, offset: 36 bytes
    overloaded name C
           instance C::C(void)
           instance C::C(const C &)
    DBG>

Note that SHOW SYMBOL/FULL does not display members of base classes or derived classes. Use the commands SHOW SYMBOL/FULL base_class_name and SHOW SYMBOL/FULL derived_class_name to display information about members of those classes. For example:

    DBG> SHOW SYMBOL /FULL B1
    type B1
        struct (B1, 8 components), size: 24 bytes
          inherits: virtual A
          is inherited by: C
          contains the following members:
            i : longword integer, size: 4 bytes, offset: 0 bytes
            overloaded name B1
            void f(void)
            B1 & =(const B1 &)
            void h(void)   [virtual]
            __vptr : typed pointer type, size: 4 bytes, offset: 4 bytes
            __bptr : typed pointer type, size: 4 bytes, offset: 8 bytes
            structure has been padded, size: 12 bytes, offset: 12 bytes
    overloaded name B1
           instance B1::B1(void)
           instance B1::B1(const B1 &)
    DBG>

Use the command SHOW SYMBOL/FULL class_member_name to display information about class members. For example:

    DBG> SHOW SYMBOL /FULL j
    record component C::j
        address: offset 24 bytes from beginning of record
        atomic type, longword integer, size: 4 bytes
    record component A::j
        address: offset 4 bytes from beginning of record
        atomic type, longword integer, size: 4 bytes
    DBG>

Use the SHOW SYMBOL/FULL command to display detailed information about an object.

Note that SHOW SYMBOL does not currently support qualified names. For example, the following commands are not currently supported:

    SHOW SYMBOL    object_name.function_name

    SHOW SYMBOL    class_name::member_name

### C.6.6 Displaying Information About an Object

The debugger uses C++ symbol lookup rules to display information about objects. Use the command EXAMINE to display the current value of an object. For example:

    DBG> EXAMINE a
    CXXDOCEXAMPLE\main\a: struct A
        i:  0
        j:  1
        __vptr:     131168
    DBG>

You can also display individual object members using the member access operators, period (.) and right arrow (->), with the EXAMINE command. For example:

    DBG> EXAMINE ptr
    CXXDOCEXAMPLE\main\ptr:         40
    DBG> EXAMINE *ptr
    *CXXDOCEXAMPLE\main\ptr: struct A
        i:  0
        j:  1
        __vptr:     131168
    DBG> EXAMINE a.i
    CXXDOCEXAMPLE\main\a.i: 0
    DBG> EXAMINE ptr->i
    CXXDOCEXAMPLE\main\ptr->i:      0
    DBG>

The debugger correctly interprets virtual inheritance. For example:

    DBG> EXAMINE c
    CXXDOCEXAMPLE\main\c: struct C
        inherit B1
            inherit virtual A
                i:  8
                j:  9
                __vptr:     131200
            i:      10
            __vptr: 131232
            __bptr: 131104
        inherit B2
            inherit virtual A  (already printed, see above)
            i:      11
            __vptr: 131280
            __bptr: 131152
        j:  12
        __vptr:     131232
        __bptr:     131104
    DBG>

Use the scope resolution operator (::) to reference global variables, to reference hidden members in base classes, to explicitly reference a member that is inherited, or otherwise to name a member hidden by the current context. For example:

    DBG> EXAMINE c.j
    CXXDOCEXAMPLE\main\c.j: 12
    DBG> EXAMINE c.A::j
    CXXDOCEXAMPLE\main\c.A::j:      9
    DBG> EXAMINE x
    CXXDOCEXAMPLE\main\x:   101
    DBG> EXAMINE ::x
    CXXDOCEXAMPLE\x:        13
    DBG>

To resolve ambiguous member references, the debugger lists the members that satisfy the reference and requests an unambiguous reference to the member. For example:

    DBG> EXAMINE c.i
    %DEBUG-I-AMBIGUOUS, 'i' is ambiguous, matching the following
        CXXDOCEXAMPLE\main\c.B1::i
        CXXDOCEXAMPLE\main\c.B2::i
    %DEBUG-E-REENTER, reenter the command using a more precise pathname
    DBG> EXAMINE c.B1::i
    CXXDOCEXAMPLE\main\c.B1::i:     10
    DBG>

Use the scope resolution operator (::) to refer to static data members. For example:

    DBG> EXAMINE c.s
    CXXDOCEXAMPLE\main\c.s: 42
    DBG> EXAMINE C::s
    C::s:   42
    DBG>

Use the SHOW SYMBOL/FULL to display the class type of an object (see Section C.6.5).

### C.6.7 Setting Watchpoints

You can set watchpoints on objects. All nonstatic data members are watched (including those in base classes). Static data members are not watched when you set a watchpoint on the object. However, you can explicitly set watchpoints on static data members. For example:

    DBG> SET WATCH c
    %DEBUG-I-WPTTRACE, non-static watchpoint, tracing every instruction
    DBG> GO
    watch of CXXDOCEXAMPLE\main\c.i at CXXDOCEXAMPLE\main\%LINE 50+8
        50:     c.B2::i++;
       old value: 11
       new value: 12
    break at CXXDOCEXAMPLE\main\%LINE 51
        51:     c.s++;
    DBG> SET WATCH c.s
    DBG> GO
    watch of CXXDOCEXAMPLE\main\c.s at CXXDOCEXAMPLE\main\%LINE 51+16
        51:     c.s++;
       old value: 43
       new value: 44
    break at CXXDOCEXAMPLE\main\%LINE 53
        53:     b1.f();
    DBG>

### C.6.8 Debugging Functions

The debugger uses C++ symbol lookup rules to display information on member functions. For example:

    DBG> EXAMINE /SOURCE b1.f
    module CXXDOCEXAMPLE
        14:     void f() {}
    DBG> SET BREAK B1::f
    DBG> GO
    break at routine B1::f
        14:     void f() {}
    DBG>

The debugger correctly interprets references to the this pointer. For example:

    DBG> EXAMINE this
    B1::f::this:            16
    DBG> EXAMINE *this
    *B1::f::this: struct B1
        inherit virtual A
            i:      2
            j:      3
            __vptr: 131184
        i:  4
        __vptr:     131248
        __bptr:     131120
    DBG> EXAMINE this->i
    B1::f::this->i: 4
    DBG> EXAMINE this->j
    B1::f::this->A::j:      3
    DBG>EXAMINE i
    B1::f::this->i: 4
    DBG> EXAMINE j
    B1::f::this->A::j:      3
    DBG>

The debugger correctly references virtual member functions. For example:

    DBG> EXAMINE /SOURCE %LINE 53
    module CXXDOCEXAMPLE
        53:     b1.f();
    DBG> SET BREAK this->h
    DBG> SHOW BREAK
    breakpoint at routine B1::f
    breakpoint at routine B1::h
    !!
    !! We are at the call to B1::f made at 'c.B1::f()'.
    !! Here this->h matches C::h.
    !!
    DBG> GO
    break at routine B1::f
        14:     void f() {}
    DBG> EXAMINE /SOURCE %LINE 54
    module CXXDOCEXAMPLE
        54:     c.B1::f();
    DBG> SET BREAK this->h
    DBG> SHOW BREAK
    breakpoint at routine B1::f
    breakpoint at routine B1::h
    breakpoint at routine C::h
    !!
    !! Handling overloaded functions
    !!
    DBG> SET BREAK g
    %DEBUG-I-NOTUNQOVR, symbol 'g' is overloaded
    overloaded name C::g
           instance C::g(int)
           instance C::g(long)
           instance C::g(char)
    %DEBUG-E-REENTER, reenter the command using a more precise pathname
    DBG> SET BREAK g(int)

    DBG> CANCEL BREAK/ALL
    DBG>

If you try to set a break on an overloaded function, the debugger lists the instances of the function and requests that you specify the correct instance. For example, with Debugger Version 7.2:

    DBG> SET BREAK g
    %DEBUG-I-NOTUNQOVR, symbol 'g' is overloaded
    overloaded name C::g
           instance void g(int)
           instance void g(long)
           instance void g(char *)
    %DEBUG-E-REENTER, reenter the command using a more precise pathname
    DBG> SET BREAK g(int)
    DBG>

Note The means of displaying and specifying overloaded functions is different than in the OpenVMS Debugger Version 7.1C.

The debugger provides support for debugging constructors, destructors, and operators. For example:

    DBG> SET BREAK C
    %DEBUG-I-NOTUNQOVR, symbol 'C' is overloaded
    overloaded name C
           instance C::C(void)
           instance C::C(const C &)
    %DEBUG-E-REENTER, reenter the command using a more precise pathname
    DBG> SHOW SYMBOL /FULL ~C
    routine C::~C
       type signature: ~C(void)
        code address: #, size: 152 bytes
        procedure descriptor address: #
    DBG> SET BREAK %NAME'~C'
    DBG> SET BREAK %NAME'=='
    %DEBUG-W-UNALLOCATED, '==' is not allocated in memory (optimized away)
    %DEBUG-E-CMDFAILED, the SET BREAK command has failed
    DBG> SHOW SYMBOL /FULL ==
    routine C::==
        type signature: int ==(C &)
        address: unallocated
    DBG> SHOW BREAK
    breakpoint at routine C::~C
    DBG>

Previous | Next | Contents | Index

| privacy and legal statement |
4538PRO_068.HTML