11

In what version(s) of the C++ standards (if any) is the following well-defined?

void foo(void) {
    char *nullPtr = NULL;
    &*nullPtr;
}

Note that I am specifically asking about &*nullPtr here. I am aware that simply *nullPtr is undefined - but this is a separate question and hence the currently-linked "duplicate" is not a duplicate.

Note that I am not assigning the result to anything - the second line is a simple statement.

This should be a question with an obvious answer, but (as seemingly happens way too often on such questions) I have heard just as many people say the answer is "obviously undefined" as "obviously defined".

On a rather related note, what about the following? Should foo produce a read of c?

extern volatile char c;

void bar(void) {
    volatile char *nonnullptr = &c;
    &*nonnullptr;
}

(C version of the same question: Is &*NULL well-defined in C?)

TLW
  • 1,373
  • 9
  • 22
  • 6
    Pick a language. Language-lawyer and C/C++ don't go usually go together since C and C++ are completely different languages. That said, in C dereferencing a null pointer causes undefined behavior, but [`&*E` is equivalent to `E` even for null pointers.](https://port70.net/~nsz/c/c11/n1570.html#note102) – ad absurdum Aug 05 '18 at 04:13
  • I wish to know in both. Are you saying it would be better to create two separate questions? – TLW Aug 05 '18 at 04:15
  • 1
    To me it seems like this would be best, since this question is about language-lawyer nitpicking of two distinct languages (others may disagree). Yet I am not sure if the two languages are in agreement on this issue or not; they may be. – ad absurdum Aug 05 '18 at 04:18
  • 1
    @DavidBowling - I have done so; thank you. See [link](https://stackoverflow.com/questions/51691357/is-null-well-defined-in-c). – TLW Aug 05 '18 at 04:20
  • @Ben-Voigt - the linked question addresses \*NULL, whereas I am asking about &*NULL. These are two separate issues. (Note that in C, for instance, the former is undefined whereas the latter is defined.). As such the linked question does *not* answer my question. – TLW Aug 05 '18 at 19:23
  • @AJNeufeld - the linked question addresses \*NULL, whereas I am asking about &*NULL. These are two separate issues. (Note that in C, for instance, the former is undefined whereas the latter is defined.). As such the linked question does *not* answer my question. (My kingdom for a multinotify.) – TLW Aug 05 '18 at 19:23
  • @TLW: The third line of code in the linked question is `int* q = &*p; // undefined?` which completely covers your case. Please spend a little more time when someone offers you an existing answer. – Ben Voigt Aug 05 '18 at 19:37
  • @BenVoigt - /question/answer/, sorry. The answers do not address the case at all - they all focused in on *nullPtr even though, as I've said, in C at least the two cases are rather different. – TLW Aug 06 '18 at 02:46
  • @TLW: You should probably read this as well as it contradicts the assumptions in your question: http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#232 – Ben Voigt Aug 06 '18 at 03:42

1 Answers1

11

This is four questions in one.


&*nullPtr is well-defined in C since C99, which says of the unary & operator:

If the operand is the result of a unary * operator, neither that operator nor the & operator is evaluated and the result is as if both were omitted, [...]

See WG14 N721 and DR076.


&*nullPtr is formally undefined in all revisions of C++ (by omission: unary & is specified to produce a pointer to "the designated object", and unary * is specified to produce "an lvalue referring to the object [...] to which the expression points"; a null pointer value points to no object), although the direction of core issue 232 is to make this well-defined.


&*nonnullptr produces no volatile read of *nonnullptr. Unary & expects an lvalue operand; no lvalue conversion (for C) or lvalue-to-rvalue conversion (for C++) is performed for *nonnullptr.

T.C.
  • 133,968
  • 17
  • 288
  • 421
  • At the suggestion of @DavidBowling I have split this into C and C++ questions. – TLW Aug 05 '18 at 04:21
  • 2
    This is... amusing. So in other words in C++ it _is_ a dereference for purposes of UB, but _isn't_ for purposes of volatiles? Yay consistency. – TLW Aug 05 '18 at 05:47
  • 1
    Core Issue 232 proposed null references and has had no updates for 13 years ... it seems that it's directly is currently "going nowhere" – M.M Aug 05 '18 at 20:51
  • @M.M My understanding is that CWG simply had too many other higher-priority items. – T.C. Aug 05 '18 at 22:51