|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Command | Description |
| file | Loads the executable file that is to be debugged. |
| kill | Terminates the program you are currently debugging. |
| list | Lists sections of the source code used to generate the executable file. |
| next | Advances one line of source code in the current function, without stepping into other functions. |
| step | Advances one line of source code in the current function, and does step into other functions. |
| run | Executes the program that is currently being debugged. |
| quit | Terminates gdb. |
| watch | Enables you to examine the value of a program variable whenever the value changes. |
| break | Sets a breakpoint in the code; this causes the execution of the program to be suspended whenever this point is reached. |
| make | This command enables you to remake the executable program without quitting gdb or using another window. |
| shell | Enables you to execute UNIX shell commands without leaving gdb. |
From the programmer's perspective, you have more details to be aware of when debugging C++ code than when you are debugging C code. This is because of the C++ features such as virtual functions and exception handling. gdb has added features to
support debugging both of these C++ specific features.
As described in the "Polymorphism" section of this chapter, virtual functions are C++'s way of implementing polymorphism. This means that there may be more than one function in a program with the same name. The only way to tell these functions
apart is by their signatures. The signature of a function is composed of the types of all the arguments to the function. For example, a function with the prototype
void func(int, real);
has a signature of int,real.
You can see how this could cause gdb a few problems. For example, if you had defined a class that had a virtual function called calculate, and two objects with different definitions for this function were created, how would you set a breakpoint to
trigger on this function? You set breakpoints in C by specifying the function name as an argument to the gdb break command, as follows:
(gdb) break calculate
This does not work in the case of a virtual function because the debugger would not be able to tell which calculate you wanted the breakpoint to be set on. gdb was extended in a few ways so that it could handle virtual functions. The first way to solve
the problem is to enter the function name by specifying its prototype as well. This would be done in the following way:
break 'calculate (float)'
This would give gdb enough information to determine which function the breakpoint was meant for. A second solution that gdb supports is using a breakpoint menu. Breakpoint menus allow you to specify the function name of a function. If there is more than
one function definition for that function, it gives you a menu of choices. The first choice in the menu is to abort the break command. The second choice is to set a breakpoint on all the functions that the break command matches. The remaining choices
correspond to each function that matches the break command. The following code shows an example of a breakpoint menu:
(gdb) break shape::calculate [0] cancel [1] all [2] file: shapes.C: line number: 153 [3] file: shapes.C: line number: 207 [4] file: shapes.C: line number: 247 > 2 3 Breakpoint 1 at 0xb234: file shapes.C, line 153 Breakpoint 2 at 0xa435: file shapes.C, line 207 Multiple breakpoints were set Use the "delete" command to delete unwanted breakpoints (gdb)
Exceptions are errors that occur within your program. Exception handlers are pieces of code that are written to handle errors and potential errors. For example, if you were writing a C program and calling the malloc function to get a block of memory,
you would typically check malloc's return code to make sure the memory allocation was successful. If C supported exception handling, you could specify a function that would receive or catch exceptions, and the malloc function would send or throw an
exception to your function if one occurred.
The gdb added two new commands to support C++ exception handling: the catch command and the catch info command. The catch command is used to set a breakpoint in active exception handlers. The syntax of this command is as follows:
catch exceptions
exceptions is a list of the exceptions to catch.
The catch info command is used to display all the active exception handlers.
In addition to the gdb commands that have been added to support some of the new language features contained in C++, there are also some new set and show options. These options are listed in Table 28.3.
| Command | Description |
| set print demangle | Prints C++ names in their source form rather than in the encoded or mangled form that is passed to the assembler. |
| show print demangle | Shows whether print demangle is on or off. |
| set demangle-style | Sets the style of demangled output. The options are auto, gnu, lucid, and arm. |
| show demangle-style | Shows which demangle style is being used. |
| set print object | When displaying a pointer to an object, identifies the actual type of the object. |
| show print object | Shows whether print object is turned on or off. |
| set print vtbl | Pretty prints C++ virtual function tables. |
| show print vtbl | Shows whether print vtbl is turned on or off. |
GNU C++ comes packaged with an extensive class library. A class library is a reusable set of classes that can be used to perform a specified set of functions. Some typical examples of class libraries are class libraries that handle database access,
class libraries that handle graphical user interface programming, and class libraries that implement data structures.
Examples of graphical user interface class libraries include the Microsoft Foundation Classes and Borland's Object Windows Library, both of which are class libraries that are used for developing Windows applications.
This section introduces several of the features that are offered by the GNU C++ class library.
The GNU iostream library, called libio, implements GNU C++'s standard input and output facilities. This library is similar to the I/O libraries that are supplied by other C++ compilers. The main parts of the iostream library are the input, output, and
error streams. These correspond to the standard input, output, and error streams that are found in C and are called cin, cout, and cerr respectively. The streams can be written to and read from using the << operator for output and the >>
operator for input.
The following program uses the iostream library to perform its input and output:
#include <iostream.h>
int main ()
{
char name[10];
cout << "Please enter your name.\n";
cin >> name;
cout << "Hello, " << name << ", how is it going?\n";
}
The GNU string class extends GNU C++'s string manipulation capabilities. The stringclass essentially replaces the character array definitions that existed in C and all the stringfunctions that go along with the character arrays.
The string class adds UNIX shell type string operators to the C++ language, as well as a large number of additional operators. Table 28.4 lists many of the operators that are available with the string class.
| Operator | Meaning |
| str1 == str2 | Returns TRUE if str1 is equal to str2 |
| str1 != str2 | Returns TRUE if str1 is not equal to str2 |
| str1 < str2 | Returns TRUE if str1 is less than str2 |
| str1 <= str2 | Returns TRUE if str1 is less than or equal to str2 |
| str1 > str2 | Returns TRUE if str1 is greater than str2 |
| str1 >= str2 | Returns TRUE if str1 is greater than or equal to str2 |
| compare(str1,str2) | Compares str1 to str2 without considering the case of the characters |
| str3 = str1 + str2 | Stores the result of str1 concatenated with str2 into str3 |
A number of other operators are available in the string class for performing different types of string comparisons, concatenations, and substring extraction and manipulation.
Classes are provided in the GCC C++ class library that allow you to generate several different kinds of random numbers. The classes used to generate these numbers are the Random class and the RNG class.
The class library provides two different classes that perform data collection and analysis functions. The two classes are SampleStatistic and SampleHistogram. The SampleStatistic class provides a way of collecting samples and also provides numerous
statistical functions that can perform calculations on the collected data. Some of the calculations that can be performed are mean, variance, standard deviation, minimum, and maximum.
The SampleHistogram class is derived from the SampleStatistic class and supports the collection and display of samples in bucketed intervals.
The GNU C++ library supports two kinds of linked lists: single linked lists, implemented by the SLList class, and doubly linked lists, implemented by the DLList class. Both of these types of lists support all the standard linked list operations. A
summary of the operations that these classes support is shown in Table 28.5.
| Operator | Description |
| list.empty() | Returns TRUE if list is empty |
| list.length() | Returns the number of elements in list |
| list.prepend | Places a at the front of list |
| list.append | Places a at the end of list |
| list.join(list2) | Appends list2 to list, destroying list2 in the process |
| a = list.front() | Returns a pointer to the element that is stored at the head of the list |
| a = list.rear() | Returns a pointer to the element that is stored at the end of the list |
| a = list.remove_front() | Deletes and returns the element that is stored at the front of the list |
| list.del_front() | Deletes the first element without returning it |
| list.clear() | Deletes all items from list |
| list.ins_after(i, a) | Inserts a after position i in the list |
| list.del_after(i) | Deletes the element following position i in the list |
Doubly linked lists also support the operations listed in Table 28.6.
| Operator | Description |
| a = list.remove_rear() | Deletes and returns the element stored at the end of the list |
| list.del_real() | Deletes the last element, without returning it |
| list.ins_before(i, a) | Inserts a before position i in the list |
| list.del(i, dir) | Deletes the element at the current position and then moves forward one position if dir is positive and backward one position if dir is 0 or negative |
Plex classes are classes that behave like arrays but are much more powerful. Plex classes have the following properties:
Four different types of Plexes are defined: the FPlex, the XPlex, the RPlex, and the MPlex. The FPlex is a Plex that can grow or shrink only within declared bounds. An XPlex can dynamically grow in any direction without any restrictions. An RPlex is
almost identical to an XPlex, but it has better indexing capabilities. Finally, the MPlex is the same as an RPlex except that it allows elements to be logically deleted and restored.
Table 28.7 lists some of the operations that are valid on all four of the Plexes.
| Operation | Description |
| Plex b | Assigns a copy of Plex a to Plex b |
| b = a | Copies Plex a into b |
| a.length() | Returns the number of elements in a |
| a.empty() | Returns TRUE if a has no elements |
| a.full() | Returns TRUE if a is full |
| a.clear() | Removes all the elements from a |
| a.append | Appends Plex b to the high part of a |
| a.prepend | Prepends Plex b to the low part of a |
| a.fill(z) | Sets all elements of a equal to z |
| a.valid(i) | Returns TRUE if i is a valid index into a |
| a.low_element() | Returns a pointer to the element in the lowest position in a |
| a.high_element() | Returns a pointer to the element in the highest position in a |
Plexes are a very useful class on which many of the other classes in the GNU C++ class library are based. Some of the Stack, Queue, and Linked list types are built on top of the Plex class.
The stacks class implements the standard version of a last-in-first-out (LIFO) stack. Three different implementations of stacks are offered by the GNU C++ class library: the VStack, the XPStack, and the SLStack. The VStack is a fixed-size stack, meaning
that you must specify an upper bound on the size of the stack when you first create it. The XPStack and the SLStack are both dynamically sized stacks that are implemented in a slightly different way.
Table 28.8 lists the operations that can be performed on the Stack classes.
| Operator | Description |
| Stack st | Declares st to be a stack |
| Stack st(sz) | Declares st to be a stack of size sz |
| st.empty() | Returns TRUE if stack is empty |
| st.full() | Returns TRUE if stack is full |
| st.length() | Returns the number of elements in stack |
| st.push(x) | Puts element x onto the top of the stack |
| x = st.pop() | Removes and returns the top element from the stack |
| st.top() | Returns a pointer to the top element in the stack |
| st.del_top() | Deletes the top element from the stack without returning it |
| st.clear() | Deletes all elements from stack |
The Queue class implements a standard version of a first-in-first-out (FIFO) queue. Three different kinds of queue are provided by the GNU C++ class library: the VQueue, the XPQueue, and the SLQueue. The VQueue is a fixed-size queue, so you must specify
an upper bound on the size of this kind of queue when you first create it. The XPQueue and the SLQueue are both dynamically sized queues, so no upper bound is required. The operations supported by the Queue classes are listed in Table 28.9.
| Operator | Description |
| Queue q | Declares q to be a queue |
| Queue q(sz) | Declares q to be a queue of size sz |
| q.empty() | Returns TRUE if q is empty |
| q.full() | Returns TRUE if q is full |
| q.length() | Returns the number of elements in q |
| q.enq(x) | Adds the x element to q |
| x = q.deq() | Removes and returns an element from q |
| q.front() | Returns a pointer to the front of q |
| q.del_front() | Removes an element from q and does not return the result |
| q.clear | Removes all elements from the queue |
In addition to the normal kind of queue that is discussed in this section, the GNU C++ class library also supports double-ended queues and priority queues. Both of these types of queues have similar behavior to the regular queue. The
double-ended queue adds operators for returning a pointer to the rear of the queue and deleting elements from the rear of the queue. The priority queues are arranged so that a user has fast access to the least element in the queue. They support additional
operators that allow for searching for elements in the queue.
The Set class is used to store groups of information. The only restriction on this information is that no duplicate elements are allowed. The class library supports several different implementations of sets. All of the implementations support the same
operators. These operators are shown in Table 28.10.
| Operator | Description |
| Set s | Declares a set named s that is initially empty |
| Set s(sz) | Declares a set named s that is initially empty and has a set maximum size of sz |
| s.empty() | Returns TRUE if s is empty |
| s.length() | Returns the number of elements in s |
| i = s.add(z) | Adds z to s, returning its index value |
| s.del(z) | Deletes z from s |
| s.clear() | Removes all elements from s |
| s.contains(z) | Returns TRUE if z is in s |
| s.(i) | Returns a pointer to the element indexed by i |
| i = a.first() | Returns the index of the first item in the set |
| s.next(i) | Makes i equal to the index of the next element in s |
| i = s.seek(z) | Sets i to the index of z if z is in s, and 0 otherwise |
| set1 == set2 | Returns TRUE if set1 contains all the same elements as set2 |
| set1 != set2 | Returns TRUE if set1 does not contain all the same elements as set2 |
| set1 <= set2 | Returns TRUE if set1 is a subset of set2 |
| set1 |= set2 | Adds all elements of set2 to set1 |
| set1 -= set2 | Deletes all the elements that are contained in set2 from set1 |
| set1 &= set2 | Deletes all elements from set1 that occur in set1 and not in set2 |
The class library contains another class that is similar to sets. This class is known as the bag. A bag is a group of elements that can be in any order (just as is the case with sets) but in which there can also be duplicates. Bags use all the
operators that sets use except for the ==, !=, |=, <=, |=, -=, and &= operators. In addition, bags add two new operators for dealing with elements that are in the bag more than once. These new operators are shown in Table 28.11.
| Operator | Description |
| b.remove(z) | Deletes all occurrences of z from b |
| b.nof(z) | Returns the number of occurrences of z that are in b |
Many other classes available in the GNU C++ class library provide functions other than those listed here. In addition to what comes with the compiler, many other freely available class libraries can be useful as well.
C++ offers many advantages over C. Some of these advantages come from the concepts of object-oriented programming, and others come from the highly flexible class libraries that are available to C++ programmers. This chapter gave a brief introduction to object-oriented programming and also talked about the C++ features that exist in the GNU C compiler and the GNU debugger.