Is int &ref = ref; well formed

Is int &ref = ref; well formed


7

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?

7

  • 3

    Yes, it is undefined behavior, you can not use reference without initializing it.

    – foragerDev

    11 hours ago

  • Most probably your program will give you SIG FAULT.

    – foragerDev

    11 hours ago

  • 2

    @foragerDev Can you give me a reference from the c++ standard. No it does not give seg fault.

    – Alan

    11 hours ago

  • 1

    @foragerDev No seg fault for the first snippet int &ref = ref; Demo. Also note the question is language-lawyer

    – user12002570

    11 hours ago

  • @Alan its an undefined behavior to use reference variable before you initialize it. Language does not define anything, what will your program do. You can see this here: godbolt.org/z/T6Ks61ajK

    – foragerDev

    11 hours ago

1 Answer
1


10

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;
                       ^

3

  • Why not mention cplusplus.github.io/CWG/issues/453?

    – Language Lawyer

    10 hours ago

  • @LanguageLawyer That wording seems to imply const size_t& s = sizeof(s); should be ill-formed

    – Artyer

    10 hours ago

  • @Artyer: Because sizeof is an unevaluated context, it is not dependent on the lifetime of any object mentioned. In fact, it only cares about the type of the expression, and not its value or identity. But yeah, the restriction on "the name" seems wrong. Possibly "used" is the key, in standardese that can have a narrow meaning.

    – Ben Voigt

    9 hours ago




Leave a Reply

Your email address will not be published. Required fields are marked *