[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