[comp.lang.pascal] Shouldn't debuggers be able to debug dynamic objects?

andrew@resam.dk (Leif Andrew Rump) (01/24/91)

I experienced a rather annoying feature in TurboPascal 5.5 (but I
think the problem may exist in a lot of other (integrated) debuggers
used to debug object oriented programmes.
The program enclosed create two (2) dynamic objects: a square & a
box.
The first thing to notice is that the compiler only allow squareptr
to be used as a general object for squares & boxes! Well I could
accept that _IF_ the debugger (integrated & external (TD)) at least
would notice when I create a box! But no - it only display the
content of a square - the length has to be extracted manually!!!

program dynamic;

type
  generalptr = ^general;
  general =
    object
      destructor done;               virtual;
    end;

  squareptr = ^square;
  square =
    object(general)
      height, width : real;

      constructor init(h, w : real);
    end;

  boxptr = ^box;
  box =
    object(square)
      length : real;

      constructor init(h, w, l : real);
    end;

  destructor general.done; begin end; (* everything is done behind our back *)

  constructor square.init(h, w : real);
  begin
    height := h;
    width := w;
  end;

  constructor box.init(h, w, l : real);
  begin
    square.init(h, w);
    length := l;
  end;

const
  n = 2;

var
  general_object : array(.1..n.) of squareptr;
  nr : integer;

begin
  for nr := 1 to n do
    if odd(nr) then
      general_object(.nr.) := new(squareptr, init(3, 4))
    else
      general_object(.nr.) := new(boxptr, init(3, 4, 2));

  for nr := 1 to n do
    dispose(general_object(.nr.), done);
end.


Leif Andrew Rump, AmbraSoft A/S, Stroedamvej 50, DK-2100 Copenhagen OE, Denmark
UUCP: andrew@ambra.dk, phone: +45 39 27 11 77                /
Currently at Scandinavian Airline Systems                =======/
UUCP: andrew@resam.dk, phone: +45 32 32 51 54                \
SAS, RESAM Project Office, CPHML-V, P.O.BOX 150, DK-2770 Kastrup, Denmark

> > Read oe as: o <backspace> / (slash) and OE as O <backspace> / (slash) < <

bytor@ctt.bellcore.com (Ross Huitt) (01/25/91)

In article <1991Jan24.152256.24273@resam.dk> andrew@resam.dk (Leif Andrew Rump) writes:
>I experienced a rather annoying feature in TurboPascal 5.5 (but I
>think the problem may exist in a lot of other (integrated) debuggers
>used to debug object oriented programmes.
>The program enclosed create two (2) dynamic objects: a square & a
>box.
>The first thing to notice is that the compiler only allow squareptr
>to be used as a general object for squares & boxes! Well I could
>accept that _IF_ the debugger (integrated & external (TD)) at least
>would notice when I create a box! But no - it only display the
>content of a square - the length has to be extracted manually!!!
>
...code deleted
>
>Leif Andrew Rump, AmbraSoft A/S, Stroedamvej 50, DK-2100 Copenhagen OE, Denmark
>UUCP: andrew@ambra.dk, phone: +45 39 27 11 77                /
>Currently at Scandinavian Airline Systems                =======/
>UUCP: andrew@resam.dk, phone: +45 32 32 51 54                \
>SAS, RESAM Project Office, CPHML-V, P.O.BOX 150, DK-2770 Kastrup, Denmark
>
>> > Read oe as: o <backspace> / (slash) and OE as O <backspace> / (slash) < <

When I _know_ which derived class a base class ptr is pointing to
and I want to inspect or display the object as a derived class, a cast
is usually sufficient to get the job done.  With the Turbo products,
simply type in 'squareptr(general_object(1))' at the Display or 
Evaluate prompts.  I don't know for sure that the technique works with
Turbo Pascal or if this particular syntax is correct, but I do use the
technique with C++ frequently.

	-ross aka bytor@ctt.bellcore.com

andrew@resam.dk (Leif Andrew Rump) (01/28/91)

In <1991Jan25.145947.16431@bellcore.bellcore.com> bytor@ctt.bellcore.com (Ross Huitt) writes:

>In article <1991Jan24.152256.24273@resam.dk> andrew@resam.dk (Leif Andrew Rump) writes:
>>I experienced a rather annoying feature in TurboPascal 5.5 (but I
>>think the problem may exist in a lot of other (integrated) debuggers
>>used to debug object oriented programmes.
>>The program enclosed create two (2) dynamic objects: a square & a
>>box.
>>The first thing to notice is that the compiler only allow squareptr
>>to be used as a general object for squares & boxes! Well I could
>>accept that _IF_ the debugger (integrated & external (TD)) at least
>>would notice when I create a box! But no - it only display the
>>content of a square - the length has to be extracted manually!!!
>>
>...code deleted
>>

>When I _know_ which derived class a base class ptr is pointing to
>and I want to inspect or display the object as a derived class, a cast
>is usually sufficient to get the job done.  With the Turbo products,
>simply type in 'squareptr(general_object(1))' at the Display or 
>Evaluate prompts.  I don't know for sure that the technique works with
>Turbo Pascal or if this particular syntax is correct, but I do use the
>technique with C++ frequently.

But, but, but, ... Why can't the debugger that has _all_ the information
do this job! The main reason for me to write this letter was that one
of my programmes used a dynamic list of objects and if I was going to
use the debugger to show me the content of for example the first three
objects in a list a had to remember what type each object was and change
casts accordingly - then (as I wrote in my original letter) I surely
sill make mistakes and then the debugger only caused havoc!!!

Leif Andrew


Leif Andrew Rump, AmbraSoft A/S, Stroedamvej 50, DK-2100 Copenhagen OE, Denmark
UUCP: andrew@ambra.dk, phone: +45 39 27 11 77                /
Currently at Scandinavian Airline Systems                =======/
UUCP: andrew@resam.dk, phone: +45 32 32 51 54                \
SAS, RESAM Project Office, CPHML-V, P.O.BOX 150, DK-2770 Kastrup, Denmark

> > Read oe as: o <backspace> / (slash) and OE as O <backspace> / (slash) < <

bytor@ctt.bellcore.com (Ross Huitt) (01/28/91)

In article <1991Jan28.100213.1822@resam.dk> andrew@resam.dk (Leif Andrew Rump) writes:
>In <1991Jan25.145947.16431@bellcore.bellcore.com> bytor@ctt.bellcore.com (Ross Huitt) writes:
>
>>When I _know_ which derived class a base class ptr is pointing to
>>and I want to inspect or display the object as a derived class, a cast
>>is usually sufficient to get the job done. 
>
>But, but, but, ... Why can't the debugger that has _all_ the information
>do this job! The main reason for me to write this letter was that one
>of my programmes used a dynamic list of objects and if I was going to
>use the debugger to show me the content of for example the first three
>objects in a list a had to remember what type each object was and change
>casts accordingly - then (as I wrote in my original letter) I surely
>sill make mistakes and then the debugger only caused havoc!!!
>
>Leif Andrew
>
>UUCP: andrew@resam.dk, phone: +45 32 32 51 54                \
>> > Read oe as: o <backspace> / (slash) and OE as O <backspace> / (slash) < <

The debugger does not necessarily have _all_ of the information for
objects that are dyanmically allocated.  If a derived object is later
referenced by a base pointer the only piece of information I can
think of that a debugger could use to determine the compile-time type of
would be the pointer to the virtual function table.  If the classes
involved don't have a virtuals then even this won't work.  (I know
there are other cases, too, so don't bother flaming me.) To accomplish
what you want would require support from the compiler such as embedding
a class signature in each instance of a class.  The debugger would then
read this signature to determine the class of the object regardless
of the class of the pointer.  This level of meta-class support would
be very welcome especially if we programmers had access to it.  Its
one aspect of Smalltalk that I miss very much in C++. BTW, there
are programming techniques that you can use to determine the classes of your
objects at run time.  You would still have to use casts in the debugger,
but at least you could execute a member function to determine the
class of the object before you used a cast. 

	-bytor@ctt.bellcore.com

mas@genrad.com (Mark A. Swanson) (01/29/91)

Determining what a dynamic object is is not always possible in raw C++.
However, if one is developing within a development environment with a standard
set of object coding conventions (e.g. a required char *myclass() method)
an integrated debugger can use them to provide such functionality.

Such a layered approach is practical now and avoids having to wait years
for invention and agreement on how best to support meta-identities without
adding to C++'s minimal object overhead.