On 22 September 2014 20:03, David Krauss <david_work@me.com> wrote:

On 2014–09–23, at 12:02 AM, Jens Maurer <Jens.Maurer@gmx.net> wrote:

> So, something like the following would be ill-formed?

> That seems unimplementable, because order-of-initialization
> for global variables is unspecified between translation units.

I think what we’re fishing for is ODR-use and ill-formed/NDR.

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.

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,

  void f() { int &r = r; }
  int main() {}

is a well-formed program with defined behavior today, but does not have defined behavior and does not require a diagnostic if we made this ill-formed, NDR.


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.