From: Tom Tromey <tromey@redhat.com>
To: Project Archer <archer@sourceware.org>
Subject: [Keith Seitz] Re: [tools-team] Status 2008-09-01
Date: Wed, 02 Sep 2009 19:44:00 -0000 [thread overview]
Message-ID: <m31vmpku7t.fsf@fleche.redhat.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 185 bytes --]
Keith sent this useful email privately. It details some areas of
investigation relating to virtual methods. I'm forwarding it with his
permission, so we can have it in the archives.
[-- Attachment #2: Type: message/rfc822, Size: 6928 bytes --]
From: Keith Seitz <keiths@redhat.com>
To: Chris Moller <cmoller@redhat.com>
Cc: Tom Tromey <tromey@redhat.com>
Subject: Re: [tools-team] Status 2008-09-01
Date: Tue, 01 Sep 2009 14:55:11 -0700
Message-ID: <4A9D983F.5010707@redhat.com>
On 09/01/2009 02:15 PM, Chris Moller wrote:
> I kinda back-burnered that--to quote Keith, "I'm not even sure I
> completely understand what this task is," but I'll see what I can do
> with it.
For me, the biggest questions lie around virtual (pure and otherwise)
classes and virtual methods -- printing, listing, breaking/running,
variable/stack inspection. I've added none of this to realcpp yet. [And
as you can imagine, gdb's own c++ test suite doesn't even come close to
testing any real-world c++ usage.]
I'd like to see how gdb handles something like this (very contrived,
very stupid example):
#include <iostream>
using namespace std;
template <typename T>
class virt_math
{
public:
virtual T add (T num) = 0;
virtual T sub (T num) = 0;
virtual T mul (T num) = 0;
virtual T div (T num) { return static_cast<T> (-3); } // Yes, I know
this is really evil!
};
class base_int_math : public virt_math<int>
{
public:
base_int_math (int a) : num_ (a) { };
virtual ~base_int_math (void) { };
virtual int add (int num) { return num_ + num; }
int sub (int num) { return num_ - num; }
virtual int mul (int num) { return num_ * num; }
protected:
int num_;
};
class special_int_math : public base_int_math
{
public:
special_int_math (int a) : base_int_math (a) { }
int add (int num) { return num_ + num + 100; }
int mul (int num) { return num_ * num + 100; }
};
int
main (int argc, char* argv[])
{
virt_math<int> *obj = new special_int_math (2);
cout << "obj.add (2) = " << obj->add (2) << endl;
cout << "obj.sub (2) = " << obj->sub (2) << endl;
cout << "obj.mul (2) = " << obj->mul (2) << endl;
cout << "obj.div (2) = " << obj->div (2) << endl;
delete obj;
return 0;
}
In main, doing "print *obj" isn't particularly useful IMO (I don't know
if we could do better, though):
(gdb) p *obj
$1 = {_vptr.virt_math = 0x8048c68}
I don't think this is very useful, either:
(gdb) ptype obj
type = class virt_math<int> {
public:
virtual int add(int);
virtual int sub(int);
virtual int mul(int);
virtual int div(int);
} *
IMO, gdb should at least be able to tell us that obj is really a
special_int_math object using RTTI or something.
I'm also not so sure about this:
(gdb) p special_int_math::add
Cannot reference virtual member function "add"
(gdb) p special_int_math::mul
Cannot reference virtual member function "mul"
(gdb) p special_int_math::div
Cannot reference virtual member function "div"
(gdb) p special_int_math::sub
Cannot reference virtual member function "sub"
(gdb) p base_int_math::add
Cannot reference virtual member function "add"
(gdb) p base_int_math::sub
Cannot reference virtual member function "sub"
(gdb) p base_int_math::div
Cannot reference virtual member function "div"
(gdb) p base_int_math::mul
Cannot reference virtual member function "mul"
IMO, we should be able to figure these things out.
I also don't think this is correct (or at least user-friendly):
(gdb) break virt_math<int>::mul
the class virt_math<int> does not have any method named mul
Hint: try 'virt_math<int>::mul<TAB> or 'virt_math<int>::mul<ESC-?>
(Note leading single quote.)
(gdb) ptype virt_math<int>
type = class virt_math<int> {
public:
virtual int add(int);
virtual int sub(int);
virtual int mul(int);
virtual int div(int);
}
The ptype here should mention that most of these class members are pure
virtual (=0). As it is, it does not tell you.
I also don't like the error messages here:
(gdb) b virt_math<int>::add
the class virt_math<int> does not have any method named add
Hint: try 'virt_math<int>::add<TAB> or 'virt_math<int>::add<ESC-?>
(Note leading single quote.)
(gdb) b virt_math<int>::sub
the class virt_math<int> does not have any method named sub
Hint: try 'virt_math<int>::sub<TAB> or 'virt_math<int>::sub<ESC-?>
(Note leading single quote.)
(gdb) b virt_math<int>::div
Breakpoint 1 at 0x8048acb: file virt_math.cc, line 12.
It's not that virt_math<int> /doesn't/ have methods named "add", "mul",
and "sub", but that these are pure virtual. This is, IMO, misleading to
the user, especially since "ptype" makes no distinction between these
methods and "div" (which is virtual, but not "pure" virtual).
This one is a little less cut-n-dry IMO, but it should still "work":
(gdb) p obj->num_
There is no member or method named num_.
This isn't entirely correct. Yes, "obj" *is* literally a virt_math<int>
(which contains no fields), but it *is* also a C++ class for which we
should be able to figure out that it is *really* a special_int_math, and
therefore num_ *is* a member of that class.
There's also the question about virtual inheritance (realcpp has an
example): does printing/ptyping these things do something sane and
USEFUL for the user? I imagine we're going to get multiple vtables. Blah.
Just some of the things that I've been wanting to investigate a bit, but
haven't gotten around to it.
Keith
[-- Attachment #3: Type: text/plain, Size: 6 bytes --]
Tom
next reply other threads:[~2009-09-02 19:44 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-09-02 19:44 Tom Tromey [this message]
2009-09-02 21:44 ` Jan Kratochvil
2009-09-03 19:19 ` Tom Tromey
2009-09-23 14:08 Dragos Tatulea
2009-09-25 18:40 ` Tom Tromey
2009-09-25 19:39 ` Dragos Tatulea
2009-09-25 20:45 ` Tom Tromey
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=m31vmpku7t.fsf@fleche.redhat.com \
--to=tromey@redhat.com \
--cc=archer@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).