WHY WHY WHY WHY WHY WHY

WHY WHY WHY WHY WHY WHY

Post by JKop » Tue, 22 Jun 2004 01:19:49



int monkey = ReturnIntValue();

const int& monkey = ReturnIntValue();


I once heard an argument that the binding-to-a-reference one is better
because it avoids an extra temporary. If this is so, why the hell doesn't
the following print "They're the same!!"?:



#include <iostream>

const int* g_p1;

const int* g_p2;


int Chocolate(void)
{
int monkey = 42;

g_p1 = &monkey;


return monkey;
}


int main(void)
{
const int& cream = Chocolate();

g_p2 = &cream;

if (g_p1 == g_p2)
{
std::cout << "They're the same!!";
}
{
std::cout << "They're different!!";
}

std::system("pause");

}


-JKop
 
 
 

WHY WHY WHY WHY WHY WHY

Post by JKop » Tue, 22 Jun 2004 03:20:37

JKop posted:



Well there's one extra temporary staring me in the face!
Dropped the ball on that one.

With the first one, there's 3 objects. Firstly, there's the int variable
within the function ReturnIntValue. Then there's the temporary returned.
Then there's my monkey variable in main.


With the second, there's 2 objects. Firstly, there's the int variable within
the function ReturnIntValue. Then there's the temporary returned. THIS IS
WHERE IT'S DIFFERENT: I don't create a new variable and copy it over, I hang
on to the temporary.


Which begs the question...

Why must there be a temporary? Why can't it just return the variable from
within the function.


-JKop

 
 
 

WHY WHY WHY WHY WHY WHY

Post by b_gandhi2 » Tue, 22 Jun 2004 07:01:14


Well, many things at work here.

(1) If you want to return by reference, that has to be
explicitly mentioned in the method prototype. So the
chocolate method should have signature as follows:

int &chocolate(void)

(2) You can not return by reference a local variable, in
your case, monkey is a local variable in chocolate
method. SO it should be made global. As a side remark,
the pointer g_p1 will become dangling because monkey
variable will be destroyed once control comes out of
chocolate method.

(3) There is no matching-else to the if statement in the
main(). Also because of the way standard I/O does
buffering, a cout may not result in immediate display
of the string "They are same!" or whatever, put an
endl at the end of cout: cout<<"string"<<endl;

--BG.
 
 
 

WHY WHY WHY WHY WHY WHY

Post by Gary Labow » Tue, 22 Jun 2004 10:40:02


doesn't
<<big snip>>
Is this issue still live? Anyway, response to JKop...

g_p1 contains the address of the local variable monkey, which has gone out
of scope when Chocolate returns to main. It may or may not be useable, but
certainly isn't valid, unless you like to program with undefined behaviour.
g_p2 contains the address of the temporary copy of monkey which is being
held because it was returned with the reference cream.
The two variables (the original monkey, now out of scope, and the copy of
monkey held with the reference cream) are in different places. Therefore
g_p1 and g_p2 are different.
Taking the address of a reference to a temporary seems a little bit dicey to
me --- and may well be UB.
--
Gary
 
 
 

WHY WHY WHY WHY WHY WHY

Post by Ivan Vecer » Tue, 22 Jun 2004 14:56:45


When you return a (non-static) local variable, the compiler
is allowed to make the local variable and the return-value
temporary the same.
This is called the NRVO (Named Return Value Optimization),
which some compilers do implement.

Try:

#include <iostream>

class Value
{
public:
int m;
Value(int i) : m(i) {}
Value(const Value& o) : m(o.m) { std::cout<<"Value Copied\n"; }
};

Value f()
{
Value v(5);
return v; // return may require copying
}

int main()
{
Value mine = f(); // var init may require copying
return 0;
}

Depending on how smart your compiler is, the previous program
may output "Value Copied" 0 to 2 times.


Things that may help less 'advanced' compiler optimize-out
the copies are to:
- rewrite f()'s body as:
return Value(5);
( Optimizing this out is called RVO (Return Value Optimization)
and is more commonly supported than NRVO ).
- change the type of mine() to a const-reference:
Value const& mine = f();
This may help some compilers optimize-out a copy.


hth -Ivan
--
http://www.yqcomputer.com/ ;- e-mail contact form
Brainbench MVP for C++ <> http://www.yqcomputer.com/