tags:

views:

125

answers:

3

I happened to find this code return 5. It's OK to write it this way or should definitely be avoid?

   int& f() {

     int i = 5; 
     return i;
}

int main(){

    cout<<f()<<endl;    
}
+10  A: 

If it works, it works only by accident. This is undefined behavior and should definitely be avoided.

The moment that f returns, there are no longer any guarantees as to what happens to the memory where i lived and what happens when you try to access it.

sepp2k
Agreed. +1. You might also want to look at this: http://stackoverflow.com/questions/1755010/
sbi
+4  A: 

The compiler warning is correct — you can't do that. i is likely to be overwritten at some unexpected time.

Either do

int f() { // don't return reference

     int i = 5; 
     return i;
}

int main(){

    cout<<f()<<endl;    
}

or

int &f( int &i ) { // accept reference
  // actually, in the case of modify-and-return like this,
  // you should call by value and return by value without
  // using any references. This is for illustration.

     i = 5; 
     return i;
}

int main(){
    int i
    cout<<f(i)<<endl;    
}
Potatoswatter
If you're modifying a by-reference parameter in place, returning the reference as well seems strange (second example). I'm not saying it's wrong, of course.
Steve314
@Steve: Sometimes it's the thing to do. Given the example, it would appear that he wants a reference and a return value. *shrug* In the particular case of an `int`, using references is basically incorrect.
Potatoswatter
FredOverflow
@FredOverflow - and just look at how many people really hate the stream operators. I'm not one of them, by the way, but you have to admit - they are definitely a special case in more than one way. For example, they also give a completely new meaning to old operators - not something to recommend as an everyday practice.
Steve314
+2  A: 

When the function 'f()' returns, the stack contents will be popped, and the memory address to the variable 'i' will no longer be valid. This code should not be used.

Kevin Sylvestre