Temporary global variables

I am having trouble understanding where one can use a constant reference value. Consider this test code which illustrates my difficulty:

#include <iostream>


struct reftest{
const double& refval;
reftest(const double& rrt):refval(rrt) {}
};

const double& u =45.0;
reftest rr(47.0);

int main(){


std::cout << u << std::endl;
std::cout << rr.refval << std::endl;
}

In main u keeps its value of 45, but rr.refval doesn't keep its initial value of 47. The rule that I know is that if you initialize a const reference as u above, the literal (45) is held for the entire scope, here the translation unit.
With the same logic it seems to me that 47 should also initialize rr and be maintained for the entire translation unit. As you can see on your own somehow
in the initialization of rr (const double& rrt =47) the literal is held until main() starts and then is destroyed. If "reftest rr(47.0);" is placed within main it works as I expected. I use Visual Studios 2012.

Can anyone explain this?
The temporary to which the reference is bound or the temporary that is the complete object of a subobject to which the reference is bound persists for the lifetime of the reference except:

A temporary bound to a reference member in a constructor’s ctor-initializer persists until the constructor exits.

— <other exceptions elided for brevity>
- IS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <iostream>

struct A
{
    A( double v ) : value(v) {}
    ~A()
    {
        std::cout << "A::destructor - value: " << value << "  address of value: " << &value
                   << "\n   any reference to this object is now a dangling reference\n\n" ;
    }
    const double value ;
};

struct reftest
{
    const double& refval;
    reftest(const A& rrt):refval(rrt.value) { std::cout << "constructor of reftest exits now\n\n" ; }
};

reftest rr( A(47.0) );

int main()
{
    std::cout << "we have entered main now\n" ;
    std::cout << "address of object referred to by rr.refval is: " << &(rr.refval) << '\n' ;
}

http://coliru.stacked-crooked.com/a/a5f4a0dda8a7cde7
Last edited on
Thank you, you explained it very well. I tried it and I get the same output.


I understand it to mean that in this case the temporary is assigned in the initializer list, not on a separate line of code. Therefore the temporary is destroyed after the constructor (reftest's constructor) as you showed with your "A::destructor- value" statement. You showed as well that the const pointer of reference is still in the same place as it initially was, just that the memory got reused as expected.

I got confused in part because on my system if you try:
int main()
{
reftest rr( A(47.0) );
std::cout << "we have entered main now\n" ;
std::cout << "address of object referred to by rr.refval is: " << &(rr.refval)<< '\n' ;
std::cout << rr.refval << '\n';
}

In other words, initialize reftest within main you'll find that that memory still has the initial value of 47. I suppose that is a highly implementation defined behavior and I shouldn't rely on it.

Thank you, you helped me understand references and temporary variables.
> I suppose that is a highly implementation defined behavior and I shouldn't rely on it.

It is undefined behaviour.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>

int main()
{
    int* pointer = nullptr ;

    {
        int value = 23456 ;
        pointer = &value ;
        // the life-time of the integer 'value' is over when we exit the local scope
        // however, the life-time of the pointer 'pointer' is not
    }
    // pointer now points a non-existent object

    // however, the footprint of the object may remain in the memory earlier occupied by it
    // even after its life-time is over; pointer still contains the address of that location
    // and this may well (usuually does) print out 23456

    std::cout << *pointer << '\n' ; // 23456

    // it is undefined bahaviour, though; C++ makes no guarantees as to
    // what could or what could not happen
}
I ran your examples several times because I thought you explained dangling references and pointers really well. I didn't see these examples in my c++ books. They certainly helped me understand. Thank you again.
Topic archived. No new replies allowed.