From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 71842 invoked by alias); 19 Oct 2016 14:41:31 -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 71832 invoked by uid 89); 19 Oct 2016 14:41:31 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.2 required=5.0 tests=BAYES_00,RP_MATCHES_RCVD,SPF_HELO_PASS autolearn=ham version=3.3.2 spammy=pods, forth, downsize 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; Wed, 19 Oct 2016 14:41:29 +0000 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (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 36B598F23F; Wed, 19 Oct 2016 14:41:28 +0000 (UTC) Received: from [127.0.0.1] (ovpn01.gateway.prod.ext.ams2.redhat.com [10.39.146.11]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id u9JEfQlN012179; Wed, 19 Oct 2016 10:41:27 -0400 Subject: Re: [PATCH v2 01/31] Introduce string_printf To: Trevor Saunders References: <1476839539-8374-1-git-send-email-palves@redhat.com> <1476839539-8374-2-git-send-email-palves@redhat.com> <20161019135300.37ghx3zsjincxwh7@ball> Cc: gdb-patches@sourceware.org From: Pedro Alves Message-ID: <37034a83-e419-3fba-19f7-9974b62cb693@redhat.com> Date: Wed, 19 Oct 2016 14:41: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: <20161019135300.37ghx3zsjincxwh7@ball> Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 7bit X-SW-Source: 2016-10/txt/msg00569.txt.bz2 On 10/19/2016 02:53 PM, Trevor Saunders wrote: >> +std::string >> +string_printf (const char* fmt, ...) > > std::string is unfortunately kind of large for a return value > its 4 * sizeof (void *), but maybe the simplicity matters more here. That shouldn't matter I think? Beyond a size, ABIs will return via the stack instead, and, also, no actual copying (in C++ sense) will take place, because NRVO should apply here. > >> +{ >> + std::string str; >> + va_list vp; >> + >> + /* Start by assuming some reasonable size will be sufficient. */ >> + str.resize (1024); >> + >> + while (1) >> + { >> + size_t size; >> + int result; > > you could declare these at first use right? Yeah, I considered it, and went back and forth, actually! It'd look like this instead: while (1) { va_start (vp, fmt); size_t size = str.size (); int result = vsnprintf (&str[0], size, fmt, vp); va_end (vp); str.resize (result); if (result < size) break; } Felt odd to me to see the variables declared in the middle of va_start/va_end, since those kind of form a scope. I guess I'm still not used to declaring PODs i the middle of blocks. If we don't that, then when a variable is declared in the middle of a scope it really stands out that something important might be going on with the ctor. But maybe that's just me? I can certainly change it. Also, while writing this, I was also going back and forth between doing the initial reserve: + str.resize (1024); and not doing it, and instead call vsnprintf with a NULL buffer to pre-compute the necessary size. The downsize is that you always have to call vsnprintf twice that way. The upside is less wasted memory, considering the case of these strings ending up stored in some structures. I saw today that xstrprintf (via vasprintf) uses the 'pre-compute necessary size' instead of the 'pre-reserve' approach, so I'm leaning toward doing that too now. Thanks, Pedro Alves