Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
350 views
in Technique[技术] by (71.8m points)

c++ - Why doesn't a const reference extend the life of a temporary object passed via a function?

In the following simple example, why can't ref2 be bound to the result of min(x,y+1)?

#include <cstdio>
template< typename T > const T& min(const T& a, const T& b){ return a < b ? a : b ; }

int main(){
      int x = 10, y = 2;
      const int& ref = min(x,y); //OK
      const int& ref2 = min(x,y+1); //NOT OK, WHY?
      return ref2; // Compiles to return 0
}

live example - produces:

main:
  xor eax, eax
  ret

EDIT: Below example better described a situation, I think.

#include <stdio.h>


template< typename T >
constexpr T const& min( T const& a, T const& b ) { return a < b ? a : b ; }



constexpr int x = 10;
constexpr int y = 2;

constexpr int const& ref = min(x,y);  // OK

constexpr int const& ref2 = min(x,y+1); // Compiler Error

int main()
{
      return 0;
}

live example produces:

<source>:14:38: error: '<anonymous>' is not a constant expression

 constexpr int const& ref2 = min(x,y+1);

                                      ^

Compiler returned: 1
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

It's by design. In a nutshell, only the named reference to which the temporary is bound directly will extend its lifetime.

[class.temporary]

5 There are three contexts in which temporaries are destroyed at a different point than the end of the full-expression. [...]

6 The third context is when a reference is bound to a temporary. The temporary to which the reference is bound or the temporary that is the complete object of a subobject to which the reference is bound persists for the lifetime of the reference except:

  • A temporary object bound to a reference parameter in a function call persists until the completion of the full-expression containing the call.
  • The lifetime of a temporary bound to the returned value in a function return statement is not extended; the temporary is destroyed at the end of the full-expression in the return statement.
  • [...]

You didn't bind directly to ref2, and you even pass it via a return statement. The standard explicitly says it won't extend the lifetime. In part to make certain optimizations possible. But ultimately, because keeping track of which temporary should be extended when a reference is passed in and out of functions is intractable in general.

Since compilers may optimize aggressively on the assumption that your program exhibits no undefined behavior, you see a possible manifestation of that. Accessing a value outside its lifetime is undefined, this is what return ref2; does, and since the behavior is undefined, simply returning zero is a valid behavior to exhibit. No contract is broken by the compiler.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...