United States    
COMPAQ STORE | PRODUCTS |
SERVICES | SUPPORT | CONTACT US | SEARCH
cxxtitle.gif (12116 bytes)
Compaq C++

Compaq C++
Using Compaq C++ for Tru64 UNIX Systems


Previous Contents Index

8.13 Class Templates and Function Templates

The debugger provides support for debugging class templates and function templates in much the same way as other classes and functions in C++, with the limitations described in this section.

You can use the whatis command on an instantiation of the function template as shown in Example 8-22.

Example 8-22 Example of a Function Template

(Ladebug) list 1
      1 // remember to compile with -define_templates 
      2 template<class T> int compare(T t1, T t2) 
      3 { 
      4         if (t1 < t2) return 0; 
      5         else         return 1; 
      6 } 
      7 
      8 main() 
      9 { 
>    10         int i = compare(1,2); 
     11 } 
(Ladebug) whatis compare
int compare (int, int) 
(Ladebug) 

You can set a breakpoint in a template function as shown in Example 8-23.

Example 8-23 Setting a Breakpoint in the Template Function

(Ladebug) stop in compare
[#2: stop in compare(int, int) ] 
(Ladebug) run
[2] stopped at [compare(int, int):4 0x120000560]   
      4         if (t1 < t2) return 0; 
(Ladebug) 

As shown in Example 8-24, while inside the function template, you can set or ask for the current function context, and the instantiated function will be displayed.

Example 8-24 Displaying the Current Function Context for a Function Template

(Ladebug) func
compare(int, int) in c++functemp.C line No. 4: 
      4         if (t1 < t2) return 0; 
(Ladebug) 

For class templates, you cannot use the whatis command with the template name, but you can use the whatis command on a specific instantiation of the class template. This is the instantiated name that the debugger prints when it encounters variables of the template class type. Example 8-25 displays the class definition of a particular instantiation of a parameterized stack.

Example 8-25 Displaying an Instantiated Class Template

(Ladebug) list 1, 24
      1 #include <iostream.h> 
      2 
      3 template <class T, int size> class stack { 
      4         T s[size]; 
      5         int top; 
      6 public: 
      7         stack() { top = 0; } 
      8         void push(T item) 
      9              { 
     10               s[top++] = item; 
     11              } 
     12         T pop(); 
     13 }; 
     14 
     15 template<class T, int size> T stack<T,size>::pop() 
     16 { 
     17         return s[--top]; 
     18 } 
     19 
     20 stack<int,10*10> S; 
     21 stack<double,10> F; 
     22 
     23 #pragma define_template stack<int,100> 
     24 #pragma define_template stack<double,10> 
(Ladebug) whatis stack<int,100>
class stack<int,100>  { 
  array [subrange 0 ... 99 of int] of int s; 
  int top; 
  stack<int,100> (void); 
  void push (int); 
  int pop (void); 
} stack<int,100> 
(Ladebug) 

Similarly, as shown in Example 8-26, you can use the whatis S command. The instance of S is displayed as stack<int,100> rather than just S.

Example 8-26 Displaying an Instantiated Class Template

(Ladebug) whatis S
class stack<int,100>  { 
  array [subrange 0 ... 99 of int] of int s; 
  int top; 
  stack<int,100> (void); 
  void push (int); 
  int pop (void); 
} S 
(Ladebug) 

As shown in Example 8-27, you can set breakpoints in template functions and ask for the current function context while inside a template function.

Example 8-27 Setting Breakpoints in an Instantiated Class Function

(Ladebug) stop in S.pop
[#1: stop in stack<int,100>::pop(void) ] 
(Ladebug) run
stopped at [stack<int,100>::pop(void):17 0x120001e0c]  
     17         return s[--top]; 
(Ladebug) func
stack<int,100>::pop(void) in c++classtemp.C line No. 17: 
     17         return s[--top]; 
(Ladebug) print top
2 
(Ladebug) 

You can explicitly set your current class scope to a particular instantiation of a class template if you are not in the proper class scope. See Example 8-28 and Example 8-29.

Example 8-28 Setting Current Class Scope to an Instantiated Class

(Ladebug) stop in push
Symbol push not visible in current scope. 
push has no valid breakpoint address 
Warning: Breakpoint not set 
(Ladebug) class
Current context is not a class 
(Ladebug) class S
class stack<int,100>  { 
  array [subrange 0 ... 99 of int] of int s; 
  int top; 
  stack<int,100> (void); 
  ~stack<int,100> (void); 
  void push (int); 
  int pop (void); 
} 
(Ladebug) stop in push
[#4: stop in stack<int,100>::push(int) ] 
(Ladebug) run
[4] stopped at [stack<int,100>::push(int):10 0x120001cd0] 
     10               s[top++] = item; 
(Ladebug) 

Example 8-29 Alternate Method ofSetting Current Class Scope

(Ladebug) class stack<int,100>
class stack<int,100>  { 
  array [subrange 0 ... 99 of int] of int s; 
  int top; 
  stack<int,100> (void); 
  ~stack<int,100> (void); 
  void push (int); 
  int pop (void); 
} 
(Ladebug) stop in push
[#5: stop in stack<int,100>::push(int) ] 
(Ladebug) 

Additional limitations for debugging templates include:

8.14 Debugging C++ Exception Handlers

You can debug C++ exception handlers in programs by setting breakpoints in the exception handler or in the predefined C++ functions that are used when exceptions occur. You can also examine and modify variables that are used in exception handlers.

8.14.1 Setting Breakpoints in Exception Handlers

As shown in Example 8-30, you can set a breakpoint in an exception handler by setting a breakpoint at the line number where the code for the exception handler begins. You can then step through the exception handler, examine or modify variables, or continue executing the program.

Example 8-30 Setting Breakpoints in Exception Handlers

(Ladebug) list 24
     24     try 
     25     { 
     26          foo(); 
     27     } 
     28     catch(char * str) { printf("Caught %s.\n",str); } 
     29     catch(...) { printf("Caught something.\n"); } 
     30 
     31 return 0; 
     32 } 
(Ladebug) stop at 24
[#1: stop at "except.C":26 ] 
(Ladebug) stop in unexpected
[#2: stop in unexpected ] 
(Ladebug) run
[1] stopped at [int main(void):26 0x400370] 
     26          foo(); 
(Ladebug) cont
[2] stopped at [unexpected:631 0x4010a8] 
(Cannot find source file cxx_exc.c) 
(Ladebug) cont
In my_unexpected(). 
Caught HELP. 
Thread has finished executing 
(Ladebug) 

As this example shows, you can also set breakpoints in C++ functions used to handle exceptions as follows:
terminate Gains control when any unhandled exception occurs
unexpected Gains control when a function containing an exception specification tries to throw an exception that is not in the exception specification

8.14.2 Examining and Modifying Variables in Exception Handlers

After you set a breakpoint to stop the execution in the exception handler, you can access the variables used in the exception handler the same way you would examine and modify other program variables.

8.15 Advanced Program Information: Verbose Mode

By default, the debugger gives no information on virtual base class pointers for the following:

By setting the $verbose debugger variable to 1, you can request that this information be printed in subsequent debugger responses. This section explains the normally suppressed information that the debugger provides if the $verbose debugger variable is set to 1.

When the $verbose debugger variable is set to 1 and you display the contents of a class using the whatis command, several of the class members listed are not in the source code of the original class definition. The following line shows sample output from the whatis command:


array [subrange 0 ... 0 of int] of vtable * _\|_vptr; 

The vtable variable contains the addresses of all virtual functions associated with the class. Several other class members are generated by the compiler for internal use. When the $verbose debugger variable is set to 1, you can see these members and reference them as you would reference any other member function.

The compiler generates additional parameters for nonstatic member functions. When the $verbose debugger variable is set to 1, these extra parameters are displayed as part of each member function's type signature. If you are specifying a version of an overloaded function by entering its type signature and the $verbose variable is set to 1, you must include these parameters. If the $verbose debugger variable is set to 0, you should not include the compiler-generated parameters in the type signature. When the $verbose variable is set to 1, the output of the dump command includes not only standard program variables but also compiler-generated temporary variables.

Example 8-31 prints class information using the whatis command when the $verbose variable is set to 1.

Example 8-31 Printing a Class Description in Verbose Mode

(Ladebug) print $verbose
0 
(Ladebug) whatis S
class S  { 
  int i; 
  int j; 
  S (void); 
  ~S (void); 
  int foo (void); 
  virtual int bar (void); 
} S 
(Ladebug) set $verbose = 1
(Ladebug) print $verbose
1 
(Ladebug) whatis S
class S  { 
  int i; 
  int j; 
  array [subrange 0 ... 0 of int] of vtbl * _\|_vptr; 
  S (S* const); 
  S (S* const, const S&); 
  ~S (S* const, int); 
  int foo (S* const); 
  S& operator = (S* const, const S&); 
  virtual int bar (S* const); 
} S 
(Ladebug) 

When displaying information on virtual base classes, the debugger prints pointers to the table describing the base class for each virtual base class object member. This pointer is known as the base pointer bptr. The bptr pointer is printed after the class member information. Example 8-32 shows a print command that displays the bptr pointer information when the $verbose variable is set to 1.

Example 8-32 Printing Base Pointer Information

(Ladebug) stop at 66
[#1: stop at "c++multinher.C":66 ] 
(Ladebug) run
0 
1 
3 
[1] stopped at [main(void):66 0x1200010b8] 
     66   printf("%d\n", dinst.f()); 
(Ladebug) whatis dinst
class D : B, C { 
  D (void); 
  ~D (void); 
  void g (void); 
} dinst 
(Ladebug) print dinst
class { 
        B = class { 
            V = class { 
                v = 1; 
                x = 3; 
            }; 
            x = 2; 
            ambig = 2; 
        }; 
        C = class { 
            V = class { 
                v = 1; 
                x = 3; 
            }; 
            ambig = 3; 
        }; 
    } 
(Ladebug) set $verbose = 1
(Ladebug) print dinst
class { 
        B = class { 
            V = class { 
                v = 1; 
                x = 3; 
            }; 
            x = 2; 
            ambig = 2; 
            _\|_bptr = 0x10001168; 
        }; 
        C = class { 
            V = class { 
                v = 1; 
                x = 3; 
            }; 
            ambig = 3; 
            _\|_bptr = 0x1000116c; 
        }; 
        _\|_bptr = 0x10001168; 
    } 
(Ladebug) 

When a class appears on the stack and the $verbose debugger variable is set to 0, the class's members are represented with an ellipsis {...}. When the $verbose debugger variable is set to 1, the debugger prints all members of classes on the stack trace.

Example 8-33 shows that member functions on the stack trace are printed with their this pointer value explicitly when the $verbose variable is set to 1.

Example 8-33 Printing a Stack Trace in Verbose Mode

(Ladebug) where
>0  0x120000789in ((S*)0x10000010)->bar(t={ ... }) c++exv.C:42 
#1  0x1200008bc in main() c++exv.C:50 
(Ladebug) set $verbose = 1
(Ladebug) where
>0  0x120000789c in ((S*)0x10000010)->bar(this=0x10000010, t=class { 
        i = 1; 
        j = 2; 
        _\|_vptr = 0x10000960; 
        virtual T::tbar = (function [0x400290]); 
    }) c++exv.C:42 
#1  0x1200008bc in main() c++exv.C:50 
(Ladebug) 


Index Contents
  

1.800.AT.COMPAQ

privacy and legal statement