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

Johannes Schaub schaub.johannes at googlemail.com
Mon Oct 24 14:50:37 PDT 2011


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. 

To elaborate on what I think the rules are, it's different for cases like 
the following

    int a[3][1] = { };
    int x = *(&a[0][0]+1);

Note that the above code is fine, since there is guaranteed to be an object 
at the dereferenced address. 

    int x = *(&a[0][0] + 2); // UB

This is undefined behavior, because the addition of 2 goes one beyond the 
after-the-end address of a[0]. Note that the following is well defined again

    int x = *(&a[0][0] + 1 + 1); // valid, not UB

Note the associativity of binary plus. Having a pointer to  a[1][0] allows 
you to add 1 again to obtain another after-the-end that again points to a 
valid object a[2][0].

To complete the picture

    (*(int*)0), 42;

This is undefined behavior, because the lvalue "*(int*)0" does not refer to 
an object or function, but an lvalue does refer to an object or function and 
C++11 does not define what happens if it doesn't (since it by definition 
can't).





More information about the cfe-dev mailing list