From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 11264 invoked by alias); 2 Sep 2009 19:44:22 -0000 Mailing-List: contact archer-help@sourceware.org; run by ezmlm Sender: Precedence: bulk List-Post: List-Help: List-Subscribe: List-Id: Received: (qmail 11251 invoked by uid 22791); 2 Sep 2009 19:44:20 -0000 X-SWARE-Spam-Status: No, hits=-2.5 required=5.0 tests=AWL,BAYES_00,SPF_HELO_PASS,SPF_PASS X-Spam-Check-By: sourceware.org From: Tom Tromey To: Project Archer Subject: [Keith Seitz] Re: [tools-team] Status 2008-09-01 Reply-To: Tom Tromey Date: Wed, 02 Sep 2009 19:44:00 -0000 Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.1 (gnu/linux) MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-SW-Source: 2009-q3/txt/msg00166.txt.bz2 --=-=-= Content-length: 185 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. --=-=-= Content-Type: message/rfc822 Content-Disposition: inline Content-length: 6907 X-From-Line: tromey Tue Sep 1 15:55:40 2009 Return-Path: keiths@redhat.com Received: from opsy [127.0.0.1] by opsy with IMAP (fetchmail-6.3.9) for (single-drop); Tue, 01 Sep 2009 15:55:40 -0600 (MDT) Received: from zmta02.collab.prod.int.phx2.redhat.com (LHLO zmta02.collab.prod.int.phx2.redhat.com) (10.5.5.32) by mail05.corp.redhat.com with LMTP; Tue, 1 Sep 2009 17:55:15 -0400 (EDT) Received: from localhost (localhost.localdomain [127.0.0.1]) by zmta02.collab.prod.int.phx2.redhat.com (Postfix) with ESMTP id 6FE5D9EF91; Tue, 1 Sep 2009 17:55:15 -0400 (EDT) Received: from zmta02.collab.prod.int.phx2.redhat.com ([127.0.0.1]) by localhost (zmta02.collab.prod.int.phx2.redhat.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 48VkP6HtwecQ; Tue, 1 Sep 2009 17:55:15 -0400 (EDT) Received: from int-mx05.intmail.prod.int.phx2.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.18]) by zmta02.collab.prod.int.phx2.redhat.com (Postfix) with ESMTP id 5CBA79EF85; Tue, 1 Sep 2009 17:55:15 -0400 (EDT) Received: from [IPv6:::1] (ovpn01.gateway.prod.ext.phx2.redhat.com [10.5.9.1]) by int-mx05.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id n81LtC78013279 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Tue, 1 Sep 2009 17:55:14 -0400 Message-ID: <4A9D983F.5010707@redhat.com> Date: Tue, 01 Sep 2009 14:55:11 -0700 From: Keith Seitz User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.1) Gecko/20090814 Fedora/3.0-2.6.b3.fc11 Lightning/1.0pre Thunderbird/3.0b3 To: Chris Moller CC: Tom Tromey Subject: Re: [tools-team] Status 2008-09-01 References: <4A9D88E2.7030604@redhat.com> <4A9D8EE0.2050103@redhat.com> In-Reply-To: <4A9D8EE0.2050103@redhat.com> X-Scanned-By: MIMEDefang 2.67 on 10.5.11.18 Lines: 158 Xref: opsy mail.cygnus:119265 MIME-Version: 1.0 Content-length: 4960 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 using namespace std; template 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 (-3); } // Yes, I know this is really evil! }; class base_int_math : public virt_math { 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 *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 { 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::mul the class virt_math does not have any method named mul Hint: try 'virt_math::mul or 'virt_math::mul (Note leading single quote.) (gdb) ptype virt_math type = class virt_math { 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::add the class virt_math does not have any method named add Hint: try 'virt_math::add or 'virt_math::add (Note leading single quote.) (gdb) b virt_math::sub the class virt_math does not have any method named sub Hint: try 'virt_math::sub or 'virt_math::sub (Note leading single quote.) (gdb) b virt_math::div Breakpoint 1 at 0x8048acb: file virt_math.cc, line 12. It's not that virt_math /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 (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 --=-=-= Content-length: 6 Tom --=-=-=--