[cfe-dev] (Request for comments) Implicit cast kind for initialization of references.

Johannes Schaub schaub.johannes at googlemail.com
Tue Oct 25 14:24:35 PDT 2011

Enea Zaffanella wrote:

> Il 25/10/2011 00:20, Abramo Bagnara ha scritto:
>> Il 24/10/2011 23:50, Johannes Schaub ha scritto:
>>> Abramo Bagnara wrote:
>>>> Il 24/10/2011 19:47, Ahmed Charles ha scritto:
>>>>> a[i] becomes *(a+i), which dereferences the address, i.e. undefined
>>>>> behavior, in your case.
>>>> Not without an lvalue to rvalue conversion.
>>> That may be the ultimate goal of the C++ committee to word into the
>>> Standard some time in the future, but the current C++11 does not
>>> incorporate that understanding yet. It leaves undefined the effects of
>>> evaluating an lvalue referring to nothing. So evaluating *(a+i) is UB
>>> *if* there is no object at address a+i. Since whether there is an object
>>> in this case is unspecified, the Standard does not require anything from
>>> the implementation - in other words, the behavior is undefined.
>> Note that from C99 times &*E is considered equivalent to E, so starting
>> from the original
>> int a[5];
>> int *p = &a[5];
>> we have the following equivalent transformations:
>> &a[5] => &*(a+5) => a + 5
>> IMHO following a different line of thought we'd soon come to nonsense.
> The wording in C++0x 8.3.2 p5 says:
>   A reference shall be initialized to refer to a valid object
>   or function. [Note: in particular, a null reference cannot
>   exist in a well-defined program, because the only way to create
>   such a reference would be to bind it to the “object” obtained
>   by dereferencing a null pointer, which causes undefined behavior.
> Now, lvalue references are initialized using lvalues. If there could be
> no invalid lvalues at all, then why stating the first sentence above?

This as stated is a diagnosable semantics rule. So when you violate it the 
implementation is required to diagnose the program. 

The note is non-normative and gives an example of where that rule is 
violated, but it also says that such a program is not well-defined anymore. 
And hence since the program becomes not well-defined anymore you are not 
required to emit a diagnostic anymore. 

So the undefined behavior does not come from the text you quoted at all, it 
comes from a different place (the mere act of dereferencing, not the binding 
of the reference).

The note continues to give an example of a violation that does not have 
undefined behavior (trying to bind a non-const reference to a bitfield), and 
that the rule you quoted renders as requiring a diagnostic.

More information about the cfe-dev mailing list