turoni
turoni

Reputation: 1435

Working on a local reference variable

I was expecting the following code to result in undefined behavior:

#include <iostream>
#include <vector>

using namespace std;

template <class T>
void incrementElements(vector<T> &v)
{
    for(typename vector<T>::size_type index = 0; index < v.size(); ++index)
    {
        T& local = v[index];
        ++local;
    }
}

int main(){
    vector<int> v;
    for(int i = 0; i < 10; ++i)
    {
        v.push_back(i);
        cout << v[v.size() - 1] << endl;
    }
    incrementElements(v);
    for(vector<int>::size_type index = 0; index < v.size(); ++index)
    {
        cout << v[index] << endl;
    }
    return 0;
}

I give a reference to my vector element to a local variable then increment it. I expected that when the local variable's lifetime ends the vector's memory would get cleaned as well resulting in empty references. Except it did give a correct output.
Is this the compiler being smart enough and fixing this behavior or is this an acceptable way to code this?

I compiled using g++ (GCC) 5.3.0

EDIT
To specify my main confusion, I wrongly was under the assumption that a reference created some sort of hard link that was equivalent to how the original variable was declared.
in my current understanding, is the following using a pointer equal:

    for(typename vector<T>::size_type index = 0; index < v.size(); ++index)
    {
        T* local = &v[index];
        ++(*local);
    }

Upvotes: 0

Views: 1598

Answers (2)

SingerOfTheFall
SingerOfTheFall

Reputation: 29966

A couple of things to note:

  • When you have UB the program can behave in any way, including the possibility of it working "correctly" (i.e. giving expected results)
  • There is no such thing as "empty reference"

Your code itself is fine, it's ok to have a reference to an object go out of scope. It is not ok to have the object that is being referenced to to go out of scope before the reference does (but note that there are cases when a const reference prolongs the lifetime of the object) and then to try use it via the reference.

Upvotes: 2

R Sahu
R Sahu

Reputation: 206557

Your code is fine.

for(typename vector<T>::size_type index = 0; index < v.size(); ++index)
{
    T& local = v[index];
    ++local;
}

is analogous to

int i = 0;
{
   int& ref = i;
   ++ref;  // Changes the value of i
}

At the end of that, you would expect to see the value of i to be 1.

  1. ref lives only in the nested scope. It can't be used outside the nested scope. It does not change the life of i.
  2. Value of i is changed inside the nested scope through ref. i continues to be alive after the nested scope ends.

Upvotes: 1

Related Questions