Search code examples
c++11gccforwarding-reference

Universal Reference and Named Parameter Ideom


I wrote this code and compile with gcc. I expected to get result "2", but result was "0".

Other compiler clang and vc prints "2". Is it undefined behaviour or not?

#include <stdio.h>

struct Test {
    Test& inc() {
        ++value;
        return *this;
    }

    int value = 1;
};

int main() {
    auto&& t = Test().inc(); // The life-time of the temporary might extended.
    printf("%d\n", t.value); // gcc prints "0". dangling reference?

    return 0;
}

c.f. build reslut on http://rextester.com


Solution

  • The forwarding reference (that's what universal references have been renamed to) is irrelevant -- you would observe the same behaviour with a regular reference.

    The issue is that the Test's lifetime is not extended, because it is not directly bound to the reference, as auto &&t = Test(); would be. Instead, its member function returns an lvalue reference, which is used to deduce and initialize t as a Test & (you can check this via decltype(t)). Then the temporary is destructed, the reference is now dangling, and using it is undefined behaviour.