C++ – Is dereferencing a pointer that’s equal to nullptr undefined behavior by the standard

clanguage-lawyer

An blog author has brought up the discussion about null pointer dereferecing:

I've put some counter arguments here:

His main line of reasoning quoting the standard is this:

The '&podhd->line6' expression is undefined behavior in the C language
when 'podhd' is a null pointer.

The C99 standard says the following about the '&' address-of operator
(6.5.3.2 "Address and indirection operators"):

The operand of the unary & operator shall be either a function
designator, the result of a [] or unary * operator, or an lvalue that
designates an object that is not a bit-field and is not declared with
the register storage-class specifier.

The expression 'podhd->line6' is clearly not a function designator,
the result of a [] or * operator. It is an lvalue expression. However,
when the 'podhd' pointer is NULL, the expression does not designate an
object since 6.3.2.3 "Pointers" says:

If a null pointer constant is converted to a pointer type, the
resulting pointer, called a null pointer, is guaranteed to compare
unequal to a pointer to any object or function.

When "an lvalue does not designate an object when it is evaluated, the
behavior is undefined" (C99 6.3.2.1 "Lvalues, arrays, and function
designators"):

An lvalue is an expression with an object type or an incomplete type
other than void; if an lvalue does not designate an object when it is
evaluated, the behavior is undefined.

So, the same idea in brief:

When -> was executed on the pointer, it evaluated to an lvalue where
no object exists, and as a result the behavior is undefined.

This question is purely language based, I'm not asking regarding whether a given system allows one to tamper with what lies at address 0 in any language.

As far as I can see, there's no restriction in dereferencing a pointer variable whose value is equal to nullptr, even thought comparisons of a pointer against the nullptr (or (void *) 0) constant can vanish in optimizations in certain situations because of the stated paragraphs, but this looks like another issue, it doesn't prevent dereferencing a pointer whose value is equal to nullptr. Notice that I've checked other SO questions and answers, I particularly like this set of quotations, as well as the standard quotes above, and I didn't stumbled upon something that clearly infers from standard that if a pointer ptr compares equal to nullptr, dereferencing it would be undefined behavior.

At most what I get is that deferencing the constant (or its cast to any pointer type) is what is UB, but nothing saying about a variable that's bit equal to the value that comes up from nullptr.

I'd like to clearly separate the nullptr constant from a pointer variable that holds a value equals to it. But an answer that address both cases is ideal.

I do realise that optimizations can quick in when there're comparisons against nullptr, etc and may simply strip code based on that.

If the conclusion is that, if ptr equals to the value of nullptr dereferencing it is definitely UB, another question follows:

Do C and C++ standards imply that a special value in the address space must exist solely to represent the value of null pointers?

Best Answer

As you quote C, dereferencing a null pointer is clearly undefined behavior from this Standard quote (emphasis mine):

(C11, 6.5.3.2p4) "If an invalid value has been assigned to the pointer, the behavior of the unary * operator is undefined.102)"

102): "Among the invalid values for dereferencing a pointer by the unary * operator are a null pointer, an address inappropriately aligned for the type of object pointed to, and the address of an object after the end of its lifetime."

Exact same quote in C99 and similar in C89 / C90.