kearns@read.columbia.edu (Steve Kearns) (06/25/89)
On pg. 43 of the "bible" it says: "an object is created when its definition is encountered and destroyed when its name goes out of scope." What about temporary variables: for example, with the following declarations... struct foo {int * dummy...}; foo foo::make(); int bar(int); ... is the lifetime of the temporary "foo" returned by foo (below) guaranteed not to be destructed until after bar returns? bar(make().dummy); This can be important when doing reference counting. The above code is more efficient than the alternative: // define bar to take a ref instead int bar(foo& ) // call bar this way bar(make()); -steve (kearns@cs.columbia.edu)
ark@alice.UUCP (Andrew Koenig) (06/25/89)
In article <6374@columbia.edu>, kearns@read.columbia.edu (Steve Kearns) writes: > On pg. 43 of the "bible" it says: > "an object is created when its definition is encountered and > destroyed when its name goes out of scope." > What about temporary variables: for example, > with the following declarations... > struct foo {int * dummy...}; > foo foo::make(); > int bar(int); > ... is the lifetime of the temporary "foo" returned by foo (below) > guaranteed not to be destructed until after bar returns? > bar(make().dummy); First of all, this example contains an error: bar takes an int argument, but foo::dummy is an int*. Moreover, the call to make() requires an object, unless the call to bar is textually inside a member function of foo. That said, here's a similar example: class Foo { public: int a; Foo(); ~Foo(); }; Foo f(); void bar(int); Given these declarations, what about bar(f().a); The answer is that once element `a' has been extracted from the value returned by f(), that value is no longer needed and can be destroyed. However, it is not required to be destroyed until the end of the block that allocated the temporary. Thus, a C++ implementation is free to do this: int temp = f().a; bar(temp); and it may destroy the temporary containing the result of f() either before or after the call to bar. Here's another closely related example: void baz(Foo&); baz(f()); Here, a reference is bound to the temporary containing the result of f() so it can be passed to baz. When a reference is bound to a temporary, the temporary is not destroyed until sometime after the reference is destroyed. Thus this particular temporary must remain at least until after baz() has returned. Similarly: Foo& r = f(); The reference `r' has been bound to the temporary containing the result of f; that temporary must therefore persist until the end of the block containing this declaration. I have written several classes that do reference counting; part of the effect of these rules is to make such classes work sensibly without much difficulty. -- --Andrew Koenig ark@europa.att.com