-3
#include <iostream>
using namespace std;

int i; //1 - global

class Test
{
public:
    ~Test()
    {
        i = 10;
    }
};

int& foo()
{
    int i = 3; //2 - local
    Test ob;
    return i;
}

int main()
{
    cout << "i = " << foo() << endl; // output: i = 3
    return 0;
}

I have queries for above code:

  1. Variable i being local to foo, reference of which cannot be used (automatic variable). How does above code execute?

  2. The Test object in foo function will be destroyed after return statement. How does foo function returns reference of 2 (i = 3)?

3 Answers3

4

Variable i being local to foo, reference of which cannot be used (automatic variable). How does above code execute?

What you are doing is cause for undefined behavior. Unfortunately, seemingly sane behavior falls under undefined behavior too. A legendary answer on SO expounds on the subject.

The Test object in foo function will be destroyed after return statement. How does foo function returns reference of 2 (i = 3)?

The first statement is correct. However, that is not relevant to the issue of which i is returned from foo. foo returns a reference to the function local variable regardless of what Test does.

R Sahu
  • 204,454
  • 14
  • 159
  • 270
2

You always read and wrote the global i since you never declared local i or class member i in your code.

timrau
  • 22,578
  • 4
  • 51
  • 64
  • This _was_ a correct answer to the posted question. Now the question has been edited to ask what I believe is a follow-up question. – Drew Dormann Jun 15 '18 at 16:51
1

when you call foo() like

cout << "i = " << foo() << endl;

This block of code will execute

int& foo() {
    i = 3; //2 - local
    Test ob; /* object having local scope */
    return i;
}/* when it goes out of this block.. destructor gets called */

above you are creating object ob. when it came out of scope, destructor ~Test() { } gets called automatically & in destructor you have i=10, so return i; will return i value which was there in destructor. so it prints i value as 10. Also i = 3; doesn't create new i it will consider global declared i.

updated code :

int& foo() {
    int i = 3; /* here i is locally created */
    Test ob;
    return i; /* you can't return reference to local variable.. invokes UB */
}

Above code block will cause undefined behavior.

Achal
  • 11,821
  • 2
  • 15
  • 37