JoJoModding <
jojoh...@gmail.com> writes:
> in the paragraph on address and indirection operators (6.5.3.2 in the
> C23 draft N3047), there is a footnote (footnote 117 in that draft),
> which says that
>
>> &*E is equivalent to E (even if E is a null pointer)
This seems to be a case where a footnote might add confusion rather than
clarity. The normative text makes it clear that &*E can't be equivalent
to E in every way because &*E is not an lvalue. And &*E has type
constraints that E does not have.
> This seems to imply that sizeof(&*E) == sizeof(E), which is unexpected
> if E is an array.
There are much simpler examples if the apparent non-equivalence. If p
is a pointer object, p can be assigned to by &*p can't be. And due to
the clause about constraints. &*(void *)0 is a constraint violation,
but (void *)0 is obviously fine.
I say "apparent" because equivalence is a slippery term. It does not
mean "exactly the same as" but something much less specific so it may
have been chosen for this very reason.
> Further, we have that
>> If an invalid value has been assigned to the pointer, the behavior of
>> the unary * operator is undefined.
>
> However the footnote says that &*E is equivalent to E, so if E is an
> invalid pointer value, *E would be undefined behavior, but &*E is not?
Yes &*p is fine even if p is an invalid pointer because undefined
behaviour only exists if *p is evaluated, and nether the * nor the & are
evaluated in &*p.
> ... &* does still remove UB even though "the constraints on the
> operators still apply"?
It removes some but not all. &*0 is a constraint violation (and hence
UB), but &*(int *)0 is not. De-referencing a null pointer is not a
constraint violation.
> How is one to read this footnote, and the paragraph in general? Why
> does it try to say that things are "equivalent" that sometimes are
> not?
Well, I think it means equivalent in some ways and not in others. But
I'm not sure it adds any clarity to the normative wording that has been
around for many years.
--
Ben.