26
int* p = 0;
int* q = &*p;

Is this undefined behavior or not? I browsed some related questions, but this specific aspect didn't show up.

8
  • duplicate: stackoverflow.com/questions/2894891/… Commented May 24, 2010 at 11:48
  • 5
    @Naveen There are no references in my program...? Commented May 24, 2010 at 11:50
  • @FredOverflow: As far I see both are doing same thing, dereferencing a null pointer which invokes undefined behavior. Commented May 24, 2010 at 12:21
  • possible duplicate of Dereferencing the null pointer Commented May 24, 2010 at 12:42
  • 3
    This is not really a duplicate of either of those questions. The question "This code appears to achieve the return of a null reference in C++" asks about C++-specific semantics (while this question asks about both C and C++) and doesn't actually ask whether dereferencing the null pointer results in undefined behavior. The question "Dereferencing the null pointer," despite its title, is actually asking "what is the null pointer?" and not "is it undefined to dereference it?" Commented May 24, 2010 at 12:53

4 Answers 4

54

The answer to this question is: it depends which language standard you are following :-).

In C90 and C++, this is not valid because you perform indirection on the null pointer (by doing *p), and doing so results in undefined behavior.

However, in C99, this is valid, well-formed, and well-defined. In C99, if the operand of the unary-& was obtained as the result of applying the unary-* or by performing subscripting ([]), then neither the & nor the * or [] is applied. For example:

int* p = 0;
int* q = &*p; // In C99, this is equivalent to int* q = p;

Likewise,

int* p = 0;
int* q = &p[0]; // In C99, this is equivalent to int* q = p + 0;

From C99 §6.5.3.2/3:

If the operand [of the unary & operator] is the result of a unary * operator, neither that operator nor the & operator is evaluated and the result is as if both were omitted, except that the constraints on the operators still apply and the result is not an lvalue.

Similarly, if the operand is the result of a [] operator, neither the & operator nor the unary * that is implied by the [] is evaluated and the result is as if the & operator were removed and the [] operator were changed to a + operator.

(and its footnote, #84):

Thus, &*E is equivalent to E (even if E is a null pointer)

Sign up to request clarification or add additional context in comments.

5 Comments

+1. What i was going to add as a comment to another answer in a hurry, until i saw this answer :)
I'll also note that it may not be the intent in C++ that performing indirection on a null pointer results in undefined behavior (per CWG defect 232). However, the proposed resolution to that defect was not incorporated into the C++0x final committee draft, so it's unlikely to be fixed before the next C++ standard is published.
I believe that in C++ this is also valid. As the unary * operator creates a reference (an alias to an object) so no de-referencing is happening. Then the & operator applied to a reference returns the NULL pointer again. See section 5.3.1-1
@Martin well we have proven you in another answer somewhere around last year that your interpretation of what "derereference" means is wrong. Applying unary * to a pointer dereferences, whether or not the lvalue to rvalue conversion is done is irrelevant. Edit: Please see the comment thread of this answer: stackoverflow.com/questions/988158/…
In particular notice the wording of 3.8/5 which says "Such a pointer may be dereferenced but the resulting lvalue may only be used in limited ways, as described below." and the various notes that make clear that "dereference" applies to transforming an address to an lvalue. The other action, transforming an lvalue to an rvalue, is not called dereference, but it's called lvalue-to-rvalue conversion or simply "accessing the stored value" (as in 3.10/15) etc.
3

Yes that would be undefined behavior, but your compiler might optimize the &* out.

Why it its undefined, is that you are attempting to access memory outside your addressable space.

3 Comments

It is undefined in all cases.
If compiler optimize it out it is some behaviour. Undefined behaviour means that anything can happen - including flying elephants and nothing.
Undefined behavior means that according to the spec, behavior is not defined. Of course, that doesn't preclude that the construct has still some well-defined behavior on other levels.
-1

Yes, dereferencing the null pointer is undefined behavior. Integer constant 0 in a pointer context is the null pointer. That's it.

Now, if your second line was int *q = p; that would be a simple pointer assignment. If the compiler removes the &* and reduces the dereference to an assignment, you're OK.

1 Comment

But it's still undefined. Just because a particular version of a particular compiler with a particular optimization level handles this doesn't mean "you're OK" - because it's undefined, it could stop working in the next release of the compiler, if the optimization level changes (or in months ending with 'R').
-1

IMHO, As far as the two code lines are concerned, there isn't any access outside the address space. The second statement is simply taking the address of (*p) which would be 'p' again and hence it will store '0'. But the location is never accessed.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.