Chapter Contents |
Previous |
Next |
SAS/C C++ Development System User's Guide, Release 6.50 |
One of the unique features of the SAS/C C++ Development System is that the debugger accepts and understands C++ function names, including multitoken and overloaded function names. This section describes how to specify C++ function names in debugger commands.
If you are specifying a nonoverloaded, single token function name in a debugger command, you do not have to do anything different from specifying a C function name. For example, you could issue the following command:
break func1 entry |
There are additional rules, however, for specifying multitoken C++ function names and overloaded function names in debugger commands. This section also explains how to specify member function names and file-scope function names.
The rules for specifying constructor and destructor function names are
unique to these types of functions and are covered separately. There is also
a section explaining how the debugger handles function names when you mix
C and C++ code and a section describing how the debugger handles translator-generated
functions (such as assignment operators and copy constructors).
Multitoken function names are function names that are not just a C++ identifier, but that contain other items such as the scope operator (::) or two-word function names such as operator and conversion functions. Here are some examples of multitoken C++ function names:
When you specify a multitoken C++ function name in a debugger command, the function name must be enclosed in double quotes. Here is an example of thebreak
command and
a multitoken function name. This command specifies to break at the entry to
member function
func1
in
class ABC
:
break "ABC::func1" entry |
One of the things that sets C++ apart from C is C++ support of overloaded functions. However, overloaded functions present a challenge for the debugger because the debugger has to determine which function you want to access.
When you specify an overloaded function name in a debugger command,
you are presented with a numbered list of C++ function names with arguments.
Determine which number represents the function you want to access, and reissue
the debugger command by appending a parenthesized number after the function
name. For example, suppose you have the following three constructors declared
in
class myclass
, in this order:
myclass(char); myclass(short); myclass(long); |
break "myclass::myclass" entry
command, the debugger shows you the
following list:
1 myclass::myclass(char) 2 myclass::myclass(short) 3 myclass::myclass(long) |
You can place a breakpoint on entry to the constructor that takes a
short
by specifying the following
break
command:
break "myclass::myclass"(2) entry |
Instead of choosing a particular number, you can specify that the command
apply to all instances of the function by using 0 as the parenthesized number.
For example, the following command sets breakpoints on entry to any
myfunc
function in
class myclass
, regardless of the argument type:
break "myclass::myfunc"(0) entry |
break, trace, ignore, runto
, and
on
.
The
debugger uses the scope operator
(::)
to determine if you want to
access either a filescope or a member function.
If you have declared both a filescope
myfunc
and a member function
myfunc
in
class ABC
, use the scope operator to tell the debugger which function
you mean when you issue debugger commands:
"::myfunc"
myfunc
."ABC::myfunc"
myfunc
in
class ABC
.myfunc
, or
only one member function named
myfunc
(but not both a file-scope
function and a member function), you can omit the scope operator and specify
just the function name in the debugger command.
Note: If the debugger is stopped in a member function when you issue
a debugger command that includes only the function name (and no scope operator),
the command works as if you were not stopped in a member function. That is,
the debugger does not automatically prefix the function name with the class
name of the class whose member function you are stopped in. This is slightly
different from the behavior for data objects, where the class name is automatically
prefixed (see Searching for Data Objects ).
When you specify a constructor or destructor in a debugger command, it must be in one of the following two forms:
class-name::class-name
"class-name::~class-name
"Here is an example of setting a breakpoint on entry to the destructor
for
class ABC
:
break "ABC::~ABC" entry |
If your load module contains at least one C++ compilation, your load module also contains a list of all function names visible to C++ compilations. If you issue a debugger command that refers to a function name not in this list, the debugger issues a warning message and assumes the function is a C function.
For example, suppose you have the following construct, where
a()
is a C++ function and
b()
and
c()
are C functions:
There is a function prototype for
b()
in the compilation containing
a()
. Because
b()
is visible
to a C++ compilation, it is contained in the debugger's list of visible function
names. But no function prototype for
c()
is visible in any C++ compilation.
Therefore,
c()
is not contained in the list of function names visible to the
debugger. If you use
c()
in a debugger command (such as in a
break
command), the debugger issues a message
that it cannot resolve the function name using the debugger file.
The debugger therefore assumes that
c()
is a C function.
Note: If you see the warning message about unresolved function names
yet you know that your program consists of only C++ functions, check the spelling
of function names in your debugger commands.
The translator creates a number of functions automatically. These functions are required by the C++ language and follow the usual C++ rules. The functions that the translator may create include constructors, copy constructors, assignment operators, and destructors. The translator creates such a function when there is not a user-defined version of the function. The list of overloaded constructors that is displayed by the debugger when you issue a debugger command may include a translator generated constructor as well as the user-defined constructors.
The following list shows the declarations for translator generated functions:
class::class()
class
. This constructor
is called whenever an object of type class is defined without an explicit
initializer.class::class(const|volatile
class&)
class
. A default
copy constructor is created for any
class
,
struct
, or
union
that does not have a user-defined
copy constructor.
The copy constructor is called to initialize an object of type
class
with another object of the same class.
The presence of
const
or
volatile
depends on the characteristics
of the class.class& class::operator=(const|volatile class&)
class
has an object assigned to it. The presence
of
const
or
volatile
depends on the characteristics of the class.class::~class()
class
goes out of scope.You may occasionally step into one of these translator-generated functions as you debug your code. When this happens, the Source window displays the source text at the class definition and the Status window displays the function name.
Chapter Contents |
Previous |
Next |
Top of Page |
Copyright © Tue Feb 10 12:11:23 EST 1998 by SAS Institute Inc., Cary, NC, USA. All rights reserved.