|
Boost : |
From: scleary_at_[hidden]
Date: 1999-12-29 12:45:08
> > Return-by-const-reference ("const T & func();")
> >
> A:
> > T x(func()); // initializes x with the object referred to by func().
> > // No temporaries.
> B:
> > const T & x = func(); // x refers to what func() referred to. No
> > // temporaries.
> >
> > Return-by-value ("T func();")
> >
> C:
> > T x(func()); // initializes x with the return value of func. One
> > // temporary.
> D:
> > const T & x = func(); // binds x to a temporary constructed from the
> > // return value of func(). One temporary
> > // (not including the one bound to x).
> >
> I agree that A and C above are equivalent.
>
> But B and D are not.
>
> In B, the lifetime of the object referenced by "x" is determined by
func().
> If func() returns a reference to a member of an object, "x" will only be
> valid as long as that object is alive. After that, use of "x" will result
in
> undefined behavior.
>
> In D, the lifetime of the object referenced by "x" is determined by the
> lifetime of "x". As long as "x" is still in scope, the object is
guaranteed
> to be good.
>
> This is a significant difference that can cause real trouble in practice.
I
> believe that returning a const reference is an idiom that trades a bit of
> efficiency for a subtle danger of a dangling reference.
>
True, but I believe that the danger of the dangling reference is implied by
the nature of the code of B and D. Anyone who writes code like A or C is
expecting a copy of the data, and gets it. Anyone who writes code like B or
D is expecting a reference to the data, and if the data's lifetime ends then
that's their problem -- it just _happens_ to still be valid for case D.
I guess what I'm saying is that code like A and C should be the norm, unless
you have a really good reason to take a nonmodifiable reference to an
internal data member (no reason comes to mind). But if you _do_ want the
reference, then it's your job to make sure that that member doesn't die
[have its lifetime end].
-Steve
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk