Christopher Smith on 17 May 2003 00:46:01 -0000


[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]

Re: [ALACPP] Chris' stupid C++ trick of the week


On Fri, 2003-05-16 at 17:26, Jon Stewart wrote:
> > The object referenced by aBar may be destroyed when you exit the doFoo()
> > block (and obviously before the caller gets a chance to look at it).
> > How? Well, the compiler actually has the option of passing arguments to
> > doFoo() by value. Of course this is only in the special case of a
> > parameter passed as a ref to a const.
> 
> I didn't know compilers were allowed to do that. It seems patently broken.

Actually a lot of languages have little odd bits like this lying about.
What makes this truly evil for me is the insidiously subtle nature of
this feature, and the fact that the type system in a templating context
makes it particularly likely that you'll trigger this case without
realizing it.

>From the compiler writer's point of view, it turns out that this is
really only a problem if your copy constructor is broken somehow (which
compilers typically make an effort to detect), or if you return the
object you passed in (which compilers typically do not detect). The
latter is usually pointless from a functional point of view (if you
already have the ref, you use that, rather than the one that came back).
The exception is when the ref you pass back may or may not be the same
as the ref that was passed in, or for cleaner looking syntax (there may
also be an operator overloading case).

> > 4) Use a compiler that always inlines templated function calls. ;-)
>
> Well, I'd prefer specifying the function as inline. It's not guaranteed to 
> work -- compilers always have the option of not-inlining -- but... I'd bet 
> most of them would take you at your word, especially for a template 
> function.

So, most compilers out there will not be able to inline an arbitrarily
complex function. Indeed, the number of cases where they can't inline
tend to be legion. Furthermore, inlining itself may prove to be a
deoptimization of such biblical purportions that the micro-optimization
of copying the object is completely blown out of the water.

Also, if you are using something like older versions of g++, for these
difficult cases, the "inline" key world will sometimes force the
compiler to do some of what you expect with inlining (avoid providing an
exportable symbol in the object code) while at the same time doing some
of the things that would make it tempting to use this optimization
(still pushing a function call onto the stack).

> Otherwise you could be lame and change the function signature to be:
> 
> doFoo(T *foo)
> 
> Pointers are cheesy, but they work (unlike references).

Yeah, more than cheesy, for me they alter the contract between caller
and callee (typically object ownership). I'd rather avoid that at all
costs.

-- 
Christopher Smith <x@xxxxxxxx>
_______________________________________________
alacpp mailing list
alacpp@xxxxxxxxxxx
http://lists.ellipsis.cx/mailman/listinfo/alacpp