From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 28196 invoked by alias); 10 Apr 2008 12:57:02 -0000 Received: (qmail 28113 invoked by uid 22791); 10 Apr 2008 12:57:02 -0000 X-Spam-Check-By: sourceware.org Received: from an-out-0708.google.com (HELO an-out-0708.google.com) (209.85.132.245) by sourceware.org (qpsmtpd/0.31) with ESMTP; Thu, 10 Apr 2008 12:56:42 +0000 Received: by an-out-0708.google.com with SMTP id c3so685943ana.104 for ; Thu, 10 Apr 2008 05:56:40 -0700 (PDT) Received: by 10.100.3.4 with SMTP id 4mr2012463anc.132.1207832200337; Thu, 10 Apr 2008 05:56:40 -0700 (PDT) Received: from ?192.168.0.11? ( [208.59.133.55]) by mx.google.com with ESMTPS id e76sm1226797hse.0.2008.04.10.05.56.38 (version=SSLv3 cipher=RC4-MD5); Thu, 10 Apr 2008 05:56:39 -0700 (PDT) Subject: Re: how to pass params to inline functions by reference or value? From: Vincent Mayeski To: Ted Byers Cc: gcc-help@gcc.gnu.org In-Reply-To: <676074.17361.qm@web88301.mail.re4.yahoo.com> References: <676074.17361.qm@web88301.mail.re4.yahoo.com> Content-Type: text/plain Date: Thu, 10 Apr 2008 13:37:00 -0000 Message-Id: <1207832200.12695.22.camel@vm-laptop> Mime-Version: 1.0 X-Mailer: Evolution 2.12.1 Content-Transfer-Encoding: 7bit X-IsSubscribed: yes Mailing-List: contact gcc-help-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-help-owner@gcc.gnu.org X-SW-Source: 2008-04/txt/msg00154.txt.bz2 Thanks Ted. I see your point. I should have included the const in the first version of the function. So we would have: inline int sum(const atype_t *x) { return x->a + x->b; } and inline int sum(atype_t x) { return x.a + x.b; } Now these two functions are semantically identical I believe. As you say, the second implementation suggests that the arg needs to be copied. However, IF the function is inlined, no copying should actually take place because the arg is not modified within the function. My guess is that these will produce identical code. If the compiler generated different code for each, then the second implementation should be faster because there is no dereferencing needed. Is this correct? On Thu, 2008-04-10 at 08:20 -0400, Ted Byers wrote: > --- VM wrote: > > Hello, > > > > I'm trying to decide on the best way to pass > > parameters to inline > > function. For example, the two functions below: > > > > inline int > > sum(atype_t *x) > > { > > return x->a + x->b; > > } > > > > and > > > > inline int > > sum(atype_t x) > > { > > return x.a + x.b; > > } > > > > Since the function is inline, my guess is that the > > compiler will > > generate identical code for both. So there should be > > no performance > > difference. > > > > Is this assumption correct? > > > > No! > > Ignore, for the moment, that you are merely advising > the compiler that you want the function inlined. > Unless things have changed since last I looked, there > is no guarantee that the compiler will inline a > function you have asked to be inlined. > > Your bigger problem is that you have ignored the > semantics associated with passing an argument by > reference, pointer and value. > > The first version of your function passes a pointer > argument. Always the same size, and since you don't > say the pointer, or the object to which it is > pointing, is const, any change made to the object > within the function remains after the function > finishes and is visible to the calling code. In the > second, you pass by value, so the copy constructor > must be called. And any change made to that object > within the function is lost when the function > completes, and is never visible to the calling code > (unless you return the object, which again will > require invoking the copy constructor). > > I would recommend you base your decisions about > whether to pass by reference or by value on what the > function needs to do to, or with, the argument object, > rather than idle speculation about what the compiler > may do IF it inlines your function. If the compiler > isn't broken, it will not change the semantics of the > function. Therefore, if you pass an object by value, > it has to be copied so that IF your function makes > changes to it, those changes are not visible to the > calling code and cease to exist once the function > completes. I would not expect inlining the function > to change that. And it gets more complicated. For > example, is there polymorphism involved, and if so, > which version of the virtual function used do you need > in the context of your function? The bottom line is > that there is no one best way to pass arguments since > what you do depends on what is needed, irrespective of > whether or not the function you're analyzing ought to > be inlined. > > HTH > > Ted