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

David Blaikie dblaikie at gmail.com
Tue Oct 25 00:51:49 PDT 2011


On Tue, Oct 25, 2011 at 12:31 AM, Enea Zaffanella
<zaffanella at cs.unipr.it> 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?

Simple - dangling references. I'm not entirely sure that the spec says
such things are immediate UB (though I suppose it should be... ).

> It is also worth to stress the use of words "in particular" in the Note
> above: as far as I understand, it suggests that the real cause of UB is
> that we are *binding* the invalid lvalue to a reference (i.e., it is not
> the mere action of computing the invalid lvalue).

I'd err the other way & assume the wording means that it's UB by
dereferencing null, not the act of binding that to a reference.

Here's at least one piece of wording from the standard that states
explicitly that the act of dereferencing something is immediate UB:

"The effect of dereferencing a pointer returned as a request for zero
size is undefined."

- 3.7.4.1 [basic.stc.dynamic.allocation] paragraph 2

Though I'm still trying to find the wording that supports the more
general/obvious case of dereferencing null (or a dangling pointer,
etc), I'd be fairly sure it's the same case.

- David




More information about the cfe-dev mailing list