On 23 September 2014 18:59, David Krauss <david_work@me.com> wrote:

On 2014–09–24, at 9:39 AM, Richard Smith <richardsmith@google.com> wrote:

> I think we simply want to say that if an id-expression naming a reference appears in its own initializer, the program is ill-formed unless the id-expression is an unevaluated operand or subexpression thereof.
>
>
> I don't think ill-formed, NDR is a good approach here: this is easy to diagnose in the "obvious" cases, and no different from other similar (non-reference) cases that lead to UB in the "non-obvious" cases, so I think we should make the obvious case ill-formed and leave the other cases as UB.

That’s only QOI. No need for standardization.

> Also, ill-formed, NDR implies that *all* executions of the program have undefined behavior (if the compiler accepts it, which it's permitted to), even if they don't actually execute the UB. For instance,

This was my intent.

Then I'm strongly opposed. It does not seem acceptable to silently change existing valid and well-defined code into having undefined behavior. I'm sure I'm not the only one who'll feel this way.

If a compiler with stronger static analysis finds any circular reference initialization, it should be allowed to balk because the program is nonsense before it ever runs.

It should be allowed to warn, and that is the status quo; if people want errors, compilers commonly have a feature to turn their warnings into errors. We don't need a language change to allow that. But allowing one compiler to reject (in its conforming mode) where another compiler accepts, for a program that runs without undefined behavior, is not reasonable. That's a disaster for portability and predictability.

A reference is supposed to have a referent. Otherwise, it may need to implement an effort to pull a result out of thin air before issuing a mere warning.

If a compiler happens to stumble on undefined behavior when emitting code, it doesn't need to put in an effort to do anything in particular. Any code it emits is fine.

> I don't think that odr-use is a good approach here, since odr-use means something else (and in particular, you can name a reference in an evaluated context without odr-using it, if it's initialized by a constant expression). That is, I want this to be ill-formed:
>
>  const int &r = true ? 0 : r;
>
> ... even though the mention of 'r' here happens to not be an odr-use.

Use in a potentially evaluated context sounds better than ODR-use, but the compiler doesn’t know that whole initializer is a constant expression at the time it’s processing the self-reference.

Exactly; that's one reason why I think we shouldn't rely on odr-use here.