5

Consider the following code -

#include <iostream>
#include <stdio.h>

const int & retRef() {
    return 6;
}

int main()
{
    const int& k = retRef();
    printf("Value: %d\n", k);
    printf("Address: %p\n", &k);
    printf("Value: %d\n", k);
    return 0;
}

The output is -

Value: 6
Address: 0x7ffd45bf544c
Value: 32692

Why the value changed after printing the address of the variable k? If I replace the line const int& k = retRef() with const int& k = 6;, the output is as expected.

Why is this different behavior? Thanks in advance

songyuanyao
  • 169,198
  • 16
  • 310
  • 405
kuro
  • 3,214
  • 3
  • 15
  • 31
  • To nitpick a little: When using the `"%p"` format with `printf`, the correct argument type is `void*`. Casting is really needed to avoid undefined behavior. Also, why use `printf` instead of `std::cout`? – Some programmer dude Dec 03 '18 at 06:55
  • The variable that you are trying to access is already cleared by system from the stack, because when the function end, its clear local variable inside that function. – Denny Kurniawan Dec 03 '18 at 06:56

3 Answers3

7

Your code has undefined behavior; You're trying to bind a temporary int (which is constructed from literal 6) to reference as return value, but the temporary will be destroyed immediately then retRef() always returns a dangled reference, and k is dangled too. Any dereference on it leads to UB.

Whenever a reference is bound to a temporary or to a subobject thereof, the lifetime of the temporary is extended to match the lifetime of the reference, with the following exceptions:

  • a temporary bound to a return value of a function in a return statement is not extended: it is destroyed immediately at the end of the return expression. Such function always returns a dangling reference.

On the other hand, const int& k = 6; works fine because the lifetime of temporary is extended to the lifetime of k as stated above.

Community
  • 1
  • 1
songyuanyao
  • 169,198
  • 16
  • 310
  • 405
4

You are returning a reference to a temporary object which will cause undefined behaviour. The object will not be available once function returns.

n4659 - § 15.2:

(6.2) — The lifetime of a temporary bound to the returned value in a function return statement (9.6.3) is not extended; the temporary is destroyed at the end of the full-expression in the return statement.

haccks
  • 104,019
  • 25
  • 176
  • 264
0

In function retRef you are returning a reference to a local variable. The objects inside the function will be destroyed when exiting the function and all references to it will become invalid. Using of that link will further entail undefined behavior...

const int & retRef()
{
    return 6;
}
snake_style
  • 1,139
  • 7
  • 16