Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is dereferencing a pointer that's equal to nullptr undefined behavior by the standard?

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

  • http://www.viva64.com/en/b/0306/

I've put some counter arguments here:

  • http://bit.ly/1L98GL4

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?

like image 203
pepper_chico Avatar asked Feb 17 '15 23:02

pepper_chico


People also ask

What does dereferencing a pointer mean?

Dereferencing is used to access or manipulate data contained in memory location pointed to by a pointer. *(asterisk) is used with pointer variable when dereferencing the pointer variable, it refers to variable being pointed, so this is called dereferencing of pointers.

Can you dereference a Nullptr?

Dereferencing a null pointer always results in undefined behavior and can cause crashes. If the compiler finds a pointer dereference, it treats that pointer as nonnull. As a result, the optimizer may remove null equality checks for dereferenced pointers.

What happens when we dereference a pointer?

The dereference operator is also known as an indirection operator, which is represented by (*). When indirection operator (*) is used with the pointer variable, then it is known as dereferencing a pointer. When we dereference a pointer, then the value of the variable pointed by this pointer will be returned.

What happens if you dereference an initialized pointer?

Response:In Hi-Tech compiler if any pointer variable is modified during code execution, the compiler will give a warning "Dereferencing uninitialized pointer" if the pointer variable is not initialised with some address.To overcome this warning , initialize the pointer variable with any address during the pointer ...


1 Answers

C++

dcl.ref/5.

There shall be no references to references, no arrays of references, and no pointers to references. The declaration of a reference shall contain an initializer (8.5.3) except when the declaration contains an explicit extern specifier (7.1.1), is a class member (9.2) declaration within a class definition, or is the declaration of a parameter or a return type (8.3.5); see 3.1. A reference shall be initialized to refer to a valid object or function. [ Note: in particular, a null reference cannot exist in a well-defined program, because the only way to create such a reference would be to bind it to the “object” obtained by indirection through a null pointer, which causes undefined behavior. As described in 9.6, a reference cannot be bound directly to a bit-field. — end note ]

The note is of interest, as it explicitly says dereferencing a null pointer is undefined.

I'm sure it says it somewhere else in a more relevant context, but this is good enough.

like image 63
Blob Avatar answered Oct 14 '22 06:10

Blob