COMPGROUPS.NET | Search | Post Question | Groups | Stream | About | Register

### Lifetime of a temporary bound to a reference

• Email
• Follow

I'm not sure what the standard says about a case like this (mainly per
12.2/5):

class B {};
class D1: public B {};
class D2: public B {};

void foo( bool r )
{
B const& a = ( r ? D1() : D2() );
// Does the temporary live here?
}

itaj

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated.    First time posters: Do this! ]

 0

See related articles to this posting

itaj sherman wrote:

> I'm not sure what the standard says about a case like this (mainly per
> 12.2/5):
>
> class B {};
> class D1: public B {};
> class D2: public B {};
>
> void foo( bool r )
> {
> B const& a = ( r ? D1() : D2() );
> // Does the temporary live here?
> }
>

First of all, that code isn't valid. Let's change it to

B const& a = ( r ? B() : D2() );

"Temporary" is a property of objects and strictly according to standards the
lifetime of it should be lengthened. But the aim of the Standard is that
only "direct" references to temporaries are lifetime-extended. What such a
"direct" reference is, however, isn't specified by the Standard as far as i
know.

In your example, even tho the result is an rvalue that definitely refers to
a temporary, that rvalue refers *either* a temporary coming from the left
*or* from the right side. Thus there is no direct reference anymore, in some
sense.

The issue around ?: and temporaries is subject of http://www.open-
std.org/jtc1/sc22/wg21/docs/cwg_active.html#462 . The direction that #462
drives toward is making "temporary" a property of expressions, instead of a
property of objects, without explicitly mentioning it in that issue report.
That issue report is the only place i know that would attribute it to
expressions explicitly. Many places in the Standard already seem to assume
that, while the text in the Standard is clear that it is a property of
objects.

To me it seems the following solves these questions too, with much less

- Say that lifetime extension rules only apply to temporaries that haven't
been bound to references or to the implicit object parameter yet.

This is sort of what the RVO rules do, saying that they only apply to
temporaries that haven't yet been bound to references. I suspect here is a
reason they haven't done this way, but i can't think of a reason.

This would allow the above conditional-expression be lifetime extended too.
It still disallows extending lifetime of a "*this" refering to a temporary
object and other such things, which is the aim of the Standard. It would
keep the term "temporary" to strictly name a property of objects.

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated.    First time posters: Do this! ]

 0

itaj sherman wrote:

> I'm not sure what the standard says about a case like this (mainly per
> 12.2/5):
>
> class B {};
> class D1: public B {};
> class D2: public B {};
>
> void foo( bool r )
> {
> B const& a = ( r ? D1() : D2() );
> // Does the temporary live here?
> }
>

I'm sorry to annoy you again, but i've just noticed that the issue report
link i gave was discussing the comma operator instead of the conditional
operator (omg, epic fail).  It turns out from links in that issue report
that the issue with the conditional operator has been fixed in C++0x by
http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#446 . It
provides the "direct reference" i talked about.

Looking at it again, i found an interesting similarity with bit-fields: An
object can be a bit-field, but an expression can be a bit-field likewise.
Like, it's said "the result is of that type and value category and it is a
bit-field if ..." at 5.16/4 in the FCD. If it would omit the addendum, the
expression would potentially refer to a bit-field, but won't be a bit-field
itself. This seems to be exactly like the situation with temporaries. The
lifetime-lengthening subsection refers to the expression property, thus it
doesn't care about lvalues that refer to temporaries, because those lvalues
won't have the "temporary" property be true. But now, i'm just more confused
how these things fit together, really :(

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated.    First time posters: Do this! ]

 0

On Jun 27, 5:27 pm, itaj sherman <itajsher...@gmail.com> wrote:
> I'm not sure what the standard says about a case like this (mainly per
> 12.2/5):
>
> class B {};
> class D1: public B {};
> class D2: public B {};
>
> void foo( bool r )
> {
>         B const& a = ( r ? D1() : D2() );
>         // Does the temporary live here?
>
> }

AFAIK, it does. E.g. ScopeGuard of Petru/Alexandrescu uses that
language feature.

Goran.

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated.    First time posters: Do this! ]

 0

On 27 June, 17:27, itaj sherman <itajsher...@gmail.com> wrote:
> I'm not sure what the standard says about a case like this (mainly per
> 12.2/5):
>
> class B {};
> class D1: public B {};
> class D2: public B {};
>
> void foo( bool r )
> {
>         B const& a = ( r ? D1() : D2() );
>         // Does the temporary live here?
>
> }

Hi, the temporary in such a case lives as long as the reference does.
http://herbsutter.com/2008/01/01/gotw-88-a-candidate-for-the-most-important-const/

Your example however will not compile, because operator ?: is not that
clever to deduce that you mean the common base type. You have to cast
at least one of the operands explicitly:

B const& a =  r ? static_cast<B&>( D1() ): D2();

Regards,
&rzej

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated.    First time posters: Do this! ]

 0

On Jun 27, 6:27 pm, itaj sherman <itajsher...@gmail.com> wrote:
> I'm not sure what the standard says about a case like this (mainly per
> 12.2/5):
>
> class B {};
> class D1: public B {};
> class D2: public B {};
>
> void foo( bool r )
> {
>         B const& a = ( r ? D1() : D2() );

//original code doesn't compile, it should have been:
B const& a = ( r ? static_cast<B const&>(D1()) : static_cast<B
const&>(D2()) );
//or:
B const& a = ( r ? B() : D2 );

>        // Does the temporary live here?

>
> }
>
> itaj
>

itaj

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated.    First time posters: Do this! ]

 0

5 Replies
119 Views

Similar Articles

12/13/2013 3:30:14 PM
[PageSpeed]

Similar Artilces:

Reference to temporary
Hello all, The code below is not legal (problem with the foo_t initializer list) because: "A reference that is not to 'const' cannot be bound to a non-lvalue" How can I best achieve an effect similar to what this code attempts? Thanks, Dave class bar_t { }; class foo_t { public: foo_t(): ref(bar_t()) {} private: bar_t &ref; }; void foo() { foo_t a; } int main() { foo(); return 0; } "Dave" <better_cs_now@yahoo.com> wrote in message news:vqj391em2v3s19@news.supernews.com... > Hello all, > > The code below is...

Assuming: #include <string> std::string get_string(); int func(const char *p); are the following valid (correct, well-defined, specified, advisable, standard, etc. etc.): char c = *get_string().c_str(); func(get_string().c_str()); Note that in the latter, there is a sequence-point after the last use of the object, so if the temporary object is deleted at that sequence point, then func() will have some problems. I saw an earlier thread on a similar topic which mentioned "full-expression"s but it did not explain this in enough detail. Finally, a &q...

I was doing a bit of experimenting prior to writing an overloaded operator, to see when a temporary was destroyed. I'm a bit unhappy at the result. This is my code (it's supposed to be a normal overloaded + and =, but with the actual calculation omitted and names used for tracking. And yes, it's a bit C-like): #include <stdio.h> #include <string.h> class Thing { char name[20]; public: Thing(char *namein); // normal constructor Thing(const Thing& other); // copy constuctor ~Thing(void); Thing operator+(const Thing& in); Thing& operator=(con...

Re: is this a reference to a temporary or not?
Joshua Lehrer wrote: > Does the following invoke undefined behavior? Yes. > The question is whether > or not a temporary is created in the call to "cast". If so, then cast > is returning a reference to a temporary, and thus "Const" is returning > a reference to a temporary which then falls out of scope. Yes, a temporary is created. > > The attempt is to convert "unsigned int *" to "const unsigned int *" > via a function call. Please, I know, use const_cast, etc... This is > a very boiled down example of a much larger...

lifetime of temporaries and ternary operator
Code: const T& val = test ? T() : T(); what is the type of the result of the ternary operator. will that temporary be bound to the reference "val" and kept alive for the lifetime of the reference? My compiler, edg front-end, says no. If my compiler is right, should the above even compile? VC++ (not sure what version) keeps the temporary alive for the lifetime of the reference. Which is right? I've already spent an hour digging through the standard, but I can't parse the jargon well enough to answer this. Thanks, joshua lehrer factset research systems NYSE:FDS ...

Hello, all-knowing Everybody, For all my self-conscious file I was sure that temporary object will be destructed right after calculating expression that using this object will be computed. However, the following example illustrates that temporary objects lives a bit longer than expression: class A { string s_; public: A(const string& s) :s_(s) { cout<<"A::A(): "<<s_<<endl; } ~A() { cout<<"~A::A(): "<<s_<<endl; } const char* operator()()const { cout<<&...

Returning a reference to a temporary object
Hi * I have a piece of code looking like this: #include <iostream> #include <string> using namespace std; string foo() { return "Something"; } int main( int, char*[]) { const std::string& value = foo(); // This is the interest point /// do something here.... return 0; } I've tested the code with MS VC 8.0 and it seems that allows me to hold a const reference to a temporary object without crashing (both debug and release targets). However, is this allowed, according to the standard? Can I use it like this? Thanks Catalin [ See http...

Pass by const-reference, temporaries and copyability
>From what I remember from the standard, passing a temporary to a function taking a const-reference requires being able to copy that temporary. GCC 4.2 does confirm it with the following code: struct Foo { Foo() {} private: Foo(const Foo&); }; void test(const Foo&) {} int main() { test(Foo()); } I get the error that Foo(const Foo&) is not accessible. It seems however that GCC 4.3 changed that behaviour: the code compiles successfully, even in standard compliant pedantic mode with all warnings. While I do like the new behaviour much better (there is really n...

Binding a reference to non-const to a temporary
Maybe I'm losing my mind, but should the following code compiler and run? (GCC says no, VC++ says yes, I'm inclined to agree with GCC): //Begin code #include <iostream> using namespace std; struct SomeClass { int m_i; SomeClass(int i) : m_i(i) { cout << "Constructing SomeClass(" << m_i << ")\n"; } SomeClass(const SomeClass &other) : m_i(other.m_i) { cout << "Copy constructing SomeClass(" << m_i << ")\n"; } }; SomeClass &Foo(SomeClass &sc) { cout << "Foo(reference): &...

lifetime of temporary object from function return & optimization
Hallo, i wonder how it is going to be of this code below regarding of the return of temporary object. Prototypes: =========== bool Activation(TCHAR *c); std::basic_string<TCHAR> GetFile(); Func Call: ========== Activation((TCHAR *) myObj.GetFile().c_str()); Summary of the Question: ======================== It works fine under EVC4 & MSVC6. However, I dont know if it is portable to g++ or other compiler. - Is there any answer to the lifetime of temporary object for all compilers? Does it also work fine under other compilers? - In cosidering of effiency of the code. Is the...

Passing a temporary by reference to function which then returns it to current context
I begin with a code part, the questions follow: // ... includes class Variables { public: // ... constructors, exception definitions const std::string& getEntry(const std::string& varName) const; const std::string& getEntry(const std::string& varName, const std::string& defaultValue) const; // ... other member functions }; // Is returning a reference ok if I call it like shown below? const std::string& Variables::getEntry(const std::string& varName, const std::string& defaultValue) const { try { return getEntry(varName); } catch ...

C++0x: returning rvalue references, recycling temporaries
[split from thread "std::max(unsigned, size_t), amd64 and C++0x"] On 11 Sep., 10:59, Howard Hinnant <howard.hinn...@gmail.com> wrote: > On Sep 9, 6:28 pm, SG <s.gesem...@gmail.com> wrote: > > > > There's some benefit to returning rvalue references: temporary objects > > can be recycled: string operator+(const string&, const string&); string && operator+(string &&, const string &); string && operator+(const string &, string &&); string && operator+(string &&, string &&); (...

Re: Non-sequential Array reference out of bounds #5 651797
David et al., Imagine a panel dataset (cross sectional time series data) with 50K observations over 30 years and 10K firms (yes, these are unbalanced). The aim is to dummy code major sic groups to test for industry effects against a variable of interest (I'm being purposely oblique as academic finance is a highly competitive research area, so research designs are not usually revealed). This is not an uncommon test and I'm not sure what you mean by " highly-correlated, multi-collinear dummy variables"? My clear sense is that dummy variables are by construction --only slightly...

How to detect const reference to temporary issues at compile or runtime? #2
Hi All I've found recently that most of the errors in my C++ programs are of a form like the following example: #include <iostream> class Z { public: Z(int n) : n(n) {} int n; }; class Y { public: Y(const Z& z) : z(z) {} const Z& z; }; class X { public: X(const Y& y) : y(y) {} Y y; }; class Big { public: Big() { for (int i = 0; i < 1000; ++i) { a[i] = i + 1000; } } int a[1000]; }; X get_x() { return X(Y(Z(123))); } int main() { X x = get_x(); Big b; std::cout << x.y.z.n << std::endl; }...

[C++03] Temporaries passed to constructor yield invalid member references
Hello. I am trying to write a class similar to this: template <class StringT> struct A { A (StringT const &str) : str(str) { } StringT const &str; }; The problem is that the constructor allows passing temporaries, which get destroyed as soon as the constructor finishes executing, not after the object is destroyed. For instance, constructing the class: A<std::string> a("hello"); would cause an implicit conversion from char const* to std::string const&, and the converted temporary will be passed to the ctor. The reference str of the class is the...

Lifetime of a temporary passed in operator[](const std::string& k)
Is this code safe? class A { public: class Proxy { public: friend class A; operator A&() { return val_.get(k_); } operator const A&() const { return val_.get(k_); } private: Proxy& operator = (const Proxy& other) {/* do nothing */} Proxy(const Proxy& proxy) : val_(proxy.val_), k_(proxy.k_) { } Proxy(A& val, const std::string& k) : val_(val), k_(k) { } A& val_; const std::string& k_; }; A& get(const std::string...

References to references
I'm trying to tie a memory function as the predicate to a find_if() operation using the following code. All I get are errors to the effect that the three different compilers can't create references to references (which I understand), yet this seems so basic to canonical STL usage that I'm at a loss. #include <list> #include <algorithm> #include <function> using namespace std; struct A { int val; }; struct B { int val; }; bool myLess(const A &lhs, const B &rhs) { return lhs.val < rhs.val; } void f() { B b; l...

Passing a reference as a reference
Hi, I have this question about Perl references. Suppose i have this %hash which has been populated with key - values.Subroutine check1 gets the %hash as a refrence from the main and this refrence has to be passed to another subroutine check2. How can this be done.Any suggestions would be helpful. ############################## my %hash; check1(\%hash); sub check1 { my ($hash)=shift; foreach my$keys (keys $hash) { print"$hash{$keys}\n"; } check2 (I want to send the reference of %hash--which is already a reference); } sub check2 { my ($hash)=shift; } ###################### Thanks ...

How to reference a previous reference in the bibliography
I'm using natbib.sty for my biliographies in LaTeX. I need to reference a previous reference in the bibliography automatically. Example: ..... 4) Gunther Garson, My Life, Hollywood Press, Florida, USA, 1954. 5) .... 6) .... 7) Reference 4, p. 112. Is there some command like (I'm making this up) \bibliocite, such that I can accomplish this by .... \bibitem{Garson}\bibliocite{Garson} Gunther Garson, {\it My Life}, Hollywood Press, Florida, USA, 1954. \bibitem{...} \bibitem{...} \bibitem{Garson2} Reference \biblioref{Garson}, p. 112. TIA. Patrick On 29 Sep 2004 10:30:22 -0700, reany...

Library Reference : ri :: Language Reference : ?
ri is cool -- library reference at your fingertips (literally ;)) Is there a gem that helps me do something similar with language reference with syntax and an example or two? For instance, \$ rubyi -> case --> multiway decision control structure --> example: tax = case income when ... then ... when ... then ... else end -> rescue ... etc. Regards, Kedar -- Posted via http://www.ruby-forum.com/. On Jan 15, 2011, at 11:10 , Kedar Mhaswade wrote: > ri is cool -- library ...