• Footnote in section on Address-Of Operator

    From JoJoModding@jojohostert@gmail.com to comp.std.c on Wed Nov 23 14:40:51 2022
    From Newsgroup: comp.std.c

    Hi all,
    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 imply that sizeof(&*E) == sizeof(E), which is unexpected if E is an array. For example, on most C compilers, we have sizeof("foo") == strlen("foo")+1, while sizeof(&*"foo") == sizeof(char*). So clearly they are not equivalent.
    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? (I'm aware that compilers may treat them equivalent, but this is precisely because *E has undefined behavior even if the immediate child of an & operator.) The sentence quoted above is not part of the constraints, so &* does still remove UB even though "the constraints on the operators still apply"?
    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?
    Thanks,
    Johannes
    --- Synchronet 3.19c-Linux NewsLink 1.113
  • From Ben Bacarisse@ben.usenet@bsb.me.uk to comp.std.c on Thu Nov 24 00:05:04 2022
    From Newsgroup: comp.std.c

    JoJoModding <jojohostert@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.
    --- Synchronet 3.19c-Linux NewsLink 1.113
  • From Tim Rentsch@tr.17687@z991.linuxsc.com to comp.std.c on Wed Nov 23 18:48:40 2022
    From Newsgroup: comp.std.c

    Ben Bacarisse <ben.usenet@bsb.me.uk> writes:

    JoJoModding <jojohostert@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.

    What makes you say &*(void*)0 is a constraint violation? I
    don't see any constraints that are violated.
    --- Synchronet 3.19c-Linux NewsLink 1.113
  • From Ben Bacarisse@ben.usenet@bsb.me.uk to comp.std.c on Thu Nov 24 13:26:13 2022
    From Newsgroup: comp.std.c

    Tim Rentsch <tr.17687@z991.linuxsc.com> writes:

    Ben Bacarisse <ben.usenet@bsb.me.uk> writes:

    JoJoModding <jojohostert@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.

    What makes you say &*(void*)0 is a constraint violation? I
    don't see any constraints that are violated.

    Isn't * applied to a pointer to an incomplete type a constraint? Let me
    go look... ah, no it is not! Thanks.
    --
    Ben.
    --- Synchronet 3.19c-Linux NewsLink 1.113