From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 13804 invoked by alias); 30 Jul 2008 17:51:15 -0000 Received: (qmail 13791 invoked by uid 22791); 30 Jul 2008 17:51:14 -0000 X-Spam-Check-By: sourceware.org Received: from smtp-out.google.com (HELO smtp-out.google.com) (216.239.33.17) by sourceware.org (qpsmtpd/0.31) with ESMTP; Wed, 30 Jul 2008 17:50:57 +0000 Received: from zps75.corp.google.com (zps75.corp.google.com [172.25.146.75]) by smtp-out.google.com with ESMTP id m6UHoPLe012022 for ; Wed, 30 Jul 2008 18:50:26 +0100 Received: from yw-out-2324.google.com (ywt2.prod.google.com [10.192.20.2]) by zps75.corp.google.com with ESMTP id m6UHnu5E009766 for ; Wed, 30 Jul 2008 10:50:24 -0700 Received: by yw-out-2324.google.com with SMTP id 2so74918ywt.33 for ; Wed, 30 Jul 2008 10:50:24 -0700 (PDT) Received: by 10.141.177.10 with SMTP id e10mr4617324rvp.112.1217440224481; Wed, 30 Jul 2008 10:50:24 -0700 (PDT) Received: by 10.151.109.14 with HTTP; Wed, 30 Jul 2008 10:50:24 -0700 (PDT) Message-ID: <8ac60eac0807301050id1051q8072925c0d11b96d@mail.gmail.com> Date: Wed, 30 Jul 2008 17:51:00 -0000 From: "Paul Pluzhnikov" To: tromey@redhat.com Subject: Re: [RFC] [patch] 'p->x' vs. 'p.x' and 'print object on' Cc: gdb-patches@sourceware.org In-Reply-To: MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Content-Disposition: inline References: <20080717214839.6AE253A67B6@localhost> X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2008-07/txt/msg00564.txt.bz2 On Mon, Jul 21, 2008 at 5:52 PM, Tom Tromey wrote: >>>>>> "Paul" == Paul Pluzhnikov writes: > > Paul> Long time GDB users are somewhat used to 'p->x' and 'p.x' meaning > Paul> the same thing. But, as test case below demonstrates, they don't > Paul> mean the same thing when 'set print object on' is in effect. > > FWIW, I like this. I was always confused when I printed an object and > saw a field, but was then unable to print the field directly. > > However, I recall bringing this up once, in the distant past. Someone > pointed out a difficulty with this approach: there might be one field > 'x' that would be used with the declared type, but another field, also > named 'x', that would be used with the actual type. So, this could > potentially be confusing (albeit in an already confusing situation). Thanks for bringing that up. I've modified the test case to have a field 'y' in both the base and derived classes (attached at the end), and the current situation is (IMHO) just as confusing before the patch as it is after :( Before patch (current behavior): Breakpoint 1, fn (f=0x7fffffffe690) at print-obj.cc:16 16 return f->y; (gdb) p *f $3 = {_vptr.Foo = 0x400570, x = 1, y = 2} (gdb) p f->y $4 = 2 (gdb) p f.y $5 = 2 (gdb) set print object on (gdb) p *f $6 = (Bar) { = {_vptr.Foo = 0x400570, x = 1, y = 2}, y = 20, z = 30} (gdb) p f->y $7 = 20 (gdb) p f.y $8 = 2 // f.y and f->y do not mean the same thing :( (gdb) finish 0x0000000000400305 in main () at print-obj.cc:22 22 return fn(&b); Value returned is $9 = 2 // Confusing: 'print f->y' says '20'; but 'finish' says '2' After: Breakpoint 1, fn (f=0x7fffffffe660) at print-obj.cc:16 16 return f->y; (gdb) p *f $1 = {_vptr.Foo = 0x400570, x = 1, y = 2} (gdb) p f->y $2 = 2 (gdb) p f.y $3 = 2 // without "print object on" patch makes no difference (gdb) set print object on (gdb) p *f $4 = (Bar) { = {_vptr.Foo = 0x400570, x = 1, y = 2}, y = 20, z = 30} (gdb) p f->y $5 = 20 (gdb) p f.y $6 = 20 // with "print object on" GDB is consistently treating f.y and f->y // as the same expression. (gdb) finish 0x0000000000400305 in main () at print-obj.cc:22 22 return fn(&b); Value returned is $7 = 2 // Still confusing ... > Maybe this can be documented or otherwise resolved. Some other alternatives (hand-simulated): A) Print both: (gbd) p f->y $14 = 2 (f->Foo::y) $15 = 20 (f->Bar::y) (gbd) p f.y $16 = 2 (f->Foo::y) $17 = 20 (f->Bar::y) B) Print warning: (gdb) p f.y Warning: more than one field 'y' resulted from lookup in dynamic type of 'f'; set 'print object off' to see the other 'y'. $18 = 20 C) Do what the language does: lookup field 'x' in the static type, and only try dynamic type if the first lookup failed: (gdb) p f.y $19 = 2 (gdb) p f->y $20 = 2 // The other field still accessible: (gdb) p f->Bar::y $21 = 20 // Lookup in Foo fails; try Bar (gdb) p f->z $22 = 30 I think "C" is the least confusing alternative. It may actually be good to do "C" independent of the 'print object' setting. > Also, IMO this patch could use an associated test case. Yes, I just wanted to see what people think about this before creating the test case. Thanks again. -- Paul Pluzhnikov // test case struct Foo { int x, y; Foo() : x(1), y(2) { } virtual ~Foo() { } virtual int method() = 0; }; struct Bar : public Foo { Bar() : y(20), z(30) { } int method() { return 42; } int y, z; }; int fn(Foo *f) { return f->y; } int main() { Bar b; return fn(&b); }