From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 124017 invoked by alias); 30 Sep 2016 02:45:55 -0000 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 Received: (qmail 124003 invoked by uid 89); 30 Sep 2016 02:45:54 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-4.9 required=5.0 tests=BAYES_00,RP_MATCHES_RCVD,SPF_HELO_PASS autolearn=ham version=3.3.2 spammy=andrei, Andrei X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 30 Sep 2016 02:45:44 +0000 Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 2CAFDC054901; Fri, 30 Sep 2016 02:45:43 +0000 (UTC) Received: from [127.0.0.1] (ovpn01.gateway.prod.ext.ams2.redhat.com [10.39.146.11]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id u8U2jfSg010820; Thu, 29 Sep 2016 22:45:41 -0400 Subject: Re: [RFA 02/22] Use RAII to save and restore scalars To: Trevor Saunders , Tom Tromey References: <1474949330-4307-1-git-send-email-tom@tromey.com> <1474949330-4307-3-git-send-email-tom@tromey.com> <20160927085937.com7c7ct4wuchzpg@ball> Cc: gdb-patches@sourceware.org From: Pedro Alves Message-ID: Date: Fri, 30 Sep 2016 09:22:00 -0000 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.2.0 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 7bit X-SW-Source: 2016-09/txt/msg00424.txt.bz2 On 09/30/2016 02:17 AM, Pedro Alves wrote: > On 09/27/2016 09:59 AM, Trevor Saunders wrote: > >>> I had hoped that template parameter deduction would work here, but it >>> did not, and so the patch uses explicit template parameters >>> everywhere. >> >> yeah, you can't deduce template args from a constructor in C++ > > I don't know whether the trick below is usual, Looks like it is -- Andrei Alexandrescu's ScopeGuard uses the same trick: http://www.drdobbs.com/cpp/generic-change-the-way-you-write-excepti/184403758 Thanks, Pedro Alves > but you can work > around that and end up with no-template-args-in-sight usage > like this: > > void > foo () > { > scoped_restore scope = make_scoped_restore (&some_global); > > ... > } > > You'd do something like this: > > > struct scoped_restore_base {}; > > template > class scoped_restore_ : public scoped_restore_base > { > public: > ... > explicit scoped_restore (T *var) > : saved_var (var), > saved_value (*var) > {} > > ~scoped_restore () > { > *saved_var = saved_value; > } > > private: > scoped_restore &operator= (const scoped_restore &rhs); > > // The saved variable. > T *saved_var; > > // The saved value. > T saved_value; > }; > > typedef const scoped_restore_base &scoped_restore; > > template > scoped_restore_ make_scoped_restore (T *var) > { > return scoped_restore_ (var); > } > > The trick is making scoped_restore_ inherit a non-template > class, and make "scoped_restore" a typedef for a const reference > to the base class, since a const reference can bind to the > temporary that is returned by make_scoped_restore, and it > extends the temporary's lifetime. > > While copy elision / RVO makes it so that the temporary returned by > value from make_scoped_restore is constructed directly in the caller > instead of constructed and then copied out, you still have to > provide the copy constructor, instead of "deleting" it as in your > original patch. Copy elision was optional until C++17, but I > believe all compilers worth their salt implement it. And if a compiler > doesn't implement it, it's not a real issue, anyway, the code > still works. > > The downside is that printing a scoped_restore object from > gdb will just print the reference using the base type, so you > won't see stored fields. > > (gdb) p scope > $1 = (const scoped_restore) @0x7fffffffd910: {} > > To see the object's fields you'd have to downcast it manually, like: > > (gdb) p (scoped_restore_) scope > $1 = { = {}, saved_var = 0x601050 , saved_value = 0x0} > > Not sure whether that's an issue. > > Thanks, > Pedro Alves >