c++referenceinitializationlanguage-lawyerselfinitialization

Is int &ref = ref; well formed


I have learned that evaluating an uninitialized variable is undefined behavior. In particular, int i = i; is undefined behavior. I have read What's the behavior of an uninitialized variable used as its own initializer?

But, is using a reference variable to initialize itself also undefined behavior? In particular, is int &ref = ref; also UB, as per the C++ standard?

int &ref = ref; // Is this well-formed or ill-formed or UB

All compilers compile the above program (with clang giving a warning). Is this because it is undefined behavior so anything is allowed to happen, or is the program well-formed?


Additionally, if I were to assign some value to ref, will the behavior of the program change from the previous case?

int &ref = ref;

int main()
{
    ref = 1; //does this change the behavior of the program from previous case
}

I noticed that for this 2nd snippet, we get a segfault.

Some references that I've read are:

What's the behavior of an uninitialized variable used as its own initializer?

Why is initialization of a new variable by itself valid?


Solution

  • It is not defined behaviour.

    [dcl.ref]p5:

    [...] A reference shall be initialized to refer to a valid object or function.

    And there is no int object to refer to.


    You could also say that the reference is being used outside of its lifetime.

    [basic.life]:

    1. The lifetime of a reference begins when its initialization is complete. The lifetime of a reference ends as if it were a scalar object requiring storage.

    2. The properties ascribed to objects and references throughout this document apply for a given object or reference only during its lifetime.

    So, the reference cannot be "used" to initialize itself before it is itself initialized, which is how Clang complains about this (https://godbolt.org/z/Ea4qPoWbs):

    note: use of reference outside its lifetime is not allowed in a constant expression
        2 |     int& ref = ref;
                           ^