C++ Logo


Advanced search

Re: [ub] Proposal: make self-initialized references ill-formed (C++17?)

From: Richard Smith <richardsmith_at_[hidden]>
Date: Wed, 24 Sep 2014 13:52:32 -0700
On 23 September 2014 18:59, David Krauss <david_work_at_[hidden]> wrote:

> On 2014–09–24, at 9:39 AM, Richard Smith <richardsmith_at_[hidden]> 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.

Received on 2014-09-24 22:52:33