question

BernardIE5317-7736 avatar image
0 Votes"
BernardIE5317-7736 asked SimpleSamples answered

Is the return value of a function a temporary object?

Why does the code below compile and run w/o error? Isn't the return value of goobar() a temporary object? Why would the compiler C++20 permit a reference to it?

 #include <iostream>
    
 using namespace std;
    
 struct cfoobar
 {
     const int& x;
     cfoobar(const int&y) : x(y) { }
 };
    
 int goobar(int x)
 {
     int y = x;
     return y;
 }
    
 int main()
 {
     cfoobar a(goobar(159));
     cout << a.x<< endl;
 }

The output is 159 just as I would not expect. Thank you kindly - cheerio

c++
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

IgorTandetnik-1300 avatar image
0 Votes"
IgorTandetnik-1300 answered RLWA32-6355 edited

This program exhibits undefined behavior, by way of accessing an object after its lifetime has ended. "Seems to work" is one possible manifestation of undefined behavior.

Yes, goobar returns a temporary. A const reference can bind to a temporary; there's nothing wrong in passing a temporary int to a function taking const int&. The problem starts when you take that temporary and store it in a data member - at that point, you make an assumption that the referred-to object will outlive the cfoobar instance. In the example, this assumption doesn't hold - the referred-to int object is destroyed soon after the constructor returns, a.x becomes a dangling reference, and an attempt to use it exhibits undefined behavior.

· 2
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Thank You for your assistance. However I still do not understand why the compiler permits this as I do not see how any temporary can outlive the constructed object it initializes.

0 Votes 0 ·

The C and C++ language standards (and compilers) have historically allowed programmers to write code that is "unsafe" or "dangerous". This results from the underlying philosophy that the programmer is trusted to do the right thing. So although the standards may point out that certain coding practices result in undefined behavior compilers do not necessarily attempt to identify and prohibit every such instance.

0 Votes 0 ·
CodeWanderer-1205 avatar image
0 Votes"
CodeWanderer-1205 answered CodeWanderer-1205 edited

The another explanation can be, that 159 is exist while it is holded by some reference. Explanation: 159 is created and added into reference and you copy reference to another. In your scenario, the reference is temporary, not a 159 itself. But I am not sure if I am right.

5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

SimpleSamples avatar image
0 Votes"
SimpleSamples answered

Originating in the days of mathematical functions before use of functions for computers the purpose of a function is to make a calculation and then provide the result of that calculation for use in further calculations. goobar returns an int; if calling cfoobar a(goobar(159)) was not the same as cfoobar a(159) then functions would be useless. Returning class objects deviates from mathematical functions but for an int it seems impossible that the standard would not require that the function return value be usable as an expression.



5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.