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.

Answer from ouah on Stack Overflow
Top answer
1 of 3
19

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.

2 of 3
5

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.

Top answer
1 of 5
3

It is not the compiler that causes your program to crash on dereferencing a null pointer. The problem is that the pointer is pointing to memory that it is illegal to reference, and the operating system kills your program for invalid behavior.

Trying to trick the compiler by obfuscating that it is a null pointer won't work, because it isn't the compiler that detects it.

There is no legitimate reason to dereference a null pointer unless you on a rare system that maps page zero (or you intend your program to crash). It is generally accepted that zeroing a pointer is a good way to mark it as invalid and dereferencing an invalid pointer is a bug. Modern operating systems do not give you a page of memory at that address specifically to make debugging invalid pointers easier.

I would not even call your program crashing from this to be undefined behavior. Dereferencing a pointer with random data in it would give you undefined behavior. Dereferencing a pointer that contains an address not assigned to your program is quite well defined in demand paged memory protected operating systems, and the behavior defined by the operating system is for your program to crash. From the language's perspective, it is still undefined behavior, because what happens is not defined in the scope of the language. Since this behavior is undefined by the language, the compiler can do nothing about it and should do nothing about it.

The exception to this is systems that have no memory protection and systems that intentionally map page zero. Some older systems do this, but most of the modern systems that do are microcontrollers, some of which might even have memory mapped I/O or some other special purpose memory in page zero.

Since null pointer dereferences are typically bugs, it is unlikely a compiler would bother to optimize away null pointer dereferences or put guard code around a possible one, as this would not improve code performance. If they did even bother to detect this, they would do it to emit a warning to assist you in debugging, similar to the "code not reachable" warning. The only reason for the compiler to generate different code around one would be if it knew what you were trying to do.

2 of 5
9

You seem to have a misunderstanding of what Undefined Behavior means.

Undefined Behavior is not something that is "caused" by your code. It is not something that happens. It is something that is.

If you have some piece of code somewhere that dereferences a null pointer, that is Undefined Behavior. UB gives the compiler a lot of leeway.

The way this is usually phrased is that the compiler is allowed to do anything. It is allowed to compile code that dereferences a null pointer into code that formats your hard disk. It is allowed to compile it into code that crashes. It is allowed to compile it into code that does random things. It is even allowed to compile it into code that doesn't crash.

And until a couple of years ago, that's mostly what compilers did. However, that isn't even the most dangerous part.

There is one thing the compiler is also allowed to do: because you are not allowed to write code that exhibits UB, the compiler is allowed to assume that there will be no UB, when optimizing your code. And because of the complex optimizations that modern compilers do, this can have very weird consequences.

Let's say you have an if (userId == 0) statement, where you have UB in the else part. Since you are not allowed to write code that exhibits UB, the compiler is allowed to assume that the else branch will never be taken. This means that the compiler is allowed to assume that userId will always be 0, i.e. it is allowed to assume that the user is always root! And based on this assumption, it is allowed to optimize away other checks as well, opening you up to huge security holes.

This can lead to very extreme, or even worse, very subtle changes to the behavior of program parts far away from the place of the UB.

🌐
Reddit
reddit.com › r/cpp_questions › what happens when dereferencing a nullptr?
r/cpp_questions on Reddit: What happens when dereferencing a nullptr?
August 18, 2022 -

I saw this code in A Tour of C++, but with a bit modify for illustration:

#include <iostream>

int main() {
  char s = 'a';
  char *p = &s;
  while (*p) {
    std::cout << *p;
    p++;
  }
  p = nullptr;
  //std::cout << (*p == true);
  *p == true;
}

I do not know how does while (*p) { end while I do not know what happens when p is nullptr. And std::cout << (*p == true) will induce segment fault but *p == true does not.

Top answer
1 of 2
4

TL;DR &(*(char*)0) is well defined.

The C++ standard doesn't say that indirection of null pointer by itself has UB. Current standard draft, [expr.unary.op]

  1. The unary * operator performs indirection: the expression to which it is applied shall be a pointer to an object type, or a pointer to a function type and the result is an lvalue referring to the object or function to which the expression points. If the type of the expression is “pointer to T”, the type of the result is “T”. [snip]

  2. The result of the unary & operator is a pointer to its operand. The operand shall be an lvalue or a qualified-id. [snip]

There is no UB unless the lvalue of the indirection expression is converted to an rvalue.


The C standard is much more explicit. C11 standard draft §6.5.3.2

  1. The unary & operator yields the address of its operand. If the operand has type "type", the result has type "pointer to type". 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, 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. Otherwise, the result is a pointer to the object or function designated by its operand.
2 of 2
1

If it is also an undefined behavior, how does offsetof work?

Prefer using the standard offsetof macro. Home-grown versions result in compiler warnings. Moreover:

offsetof is required to work as specified above, even if unary operator& is overloaded for any of the types involved. This cannot be implemented in standard C++ and requires compiler support.

offsetof is a built-in function in gcc.

🌐
Reddit
reddit.com › r/cpp › null pointer dereferencing causes undefined behavior
r/cpp on Reddit: Null Pointer Dereferencing Causes Undefined Behavior
February 16, 2015 - Despite you being correct about ... it, regardless of platform characteristics. More replies ... You should never dereference nullptr under any circumstances!...
🌐
Wikipedia
en.wikipedia.org › wiki › Null_pointer
Null pointer - Wikipedia
June 13, 2026 - Since C23, a null pointer is represented with nullptr which is of type nullptr_t (first introduced to C++11), providing a type safe null pointer. The C standard does not say that the null pointer is the same as the pointer to memory address 0, though that may be the case in practice. Dereferencing ...
🌐
Hacker News
news.ycombinator.com › item
I have a clarification: Dereferencing a null pointer in C++ *doesn’t* reliably c... | Hacker News
June 28, 2022 - For anyone who’s wondering, I’m referencing “UB” here (which is short for Undefined Behavior, but don’t be confused by the English language meaning, it’s a precise technical term in the spec). Skipping the details, there’s a surprising (and growing) amount of situations where ...
Find elsewhere
🌐
PVS-Studio
pvs-studio.com › en › blog › posts › cpp › 0306
Null Pointer Dereferencing Causes Undefined Behavior
February 16, 2015 - For instance, as proof of that code being correct they pointed out the implementation of the offsetof macro, typically looking like this: #define offsetof(st, m) ((size_t)(&((st *)0)-&gt;m)) We deal with null pointer dereferencing here, but the code still works well.
🌐
Snyk Learn
learn.snyk.io › home › security education › what is a null dereference? | tutorial & examples
What is a null dereference? | Tutorial & examples | Snyk Learn
August 15, 2024 - Pointers are variables that store the memory address of an object, and a null pointer dereference occurs when you try to access an object at a memory address that is null. In languages that use pointers, such as C and C++, null pointer dereferences ...
🌐
Quora
quora.com › How-do-I-avoid-dereferencing-null-pointers-in-C-1
How to avoid dereferencing null pointers in C++ - Quora
Answer (1 of 3): Check them for null before you use them! You can use them in an if conditition — if the pointer isn’t null, it will be true. If it is null, it will be false. You can also explicitly compare the pointer with nullptr. These work for all standard pointer types except for weak_ptr.
🌐
Reddit
reddit.com › r/embedded › what the hell gcc is doing (null ptr dereference)
r/embedded on Reddit: What the hell gcc is doing (NULL ptr dereference)
November 8, 2023 -

Guys, I'm programming cortex-m4 (stm32). I tried to read flash-memory(it is possible). Flash starts from 0. I tried to dereference NULL ptr and my mcu halted: printf("I'm dereferencing NULL pointer: %lx\r\n", *(uint32_t *)0);

Then I tried to dereference value 0x04 the same way, and it worked! I see the exact word from my binary firmware file. It means this memory region is accessible. I tried to figure out this weird thing and looked at assembly with this command: arm-none-eabi-objdump -d tanenbaum.out | less .

Look at this!: Instead of loading value to register, accessing memory region and passing it to printf and actually calling printf, like it did with number 0x04, compiler decides to insert unknown to me and cortex-m4 ISA instuction udf #255. (maybe there is such an instruction, but i didn't find it in programming manual).

8002108: 2300 movs r3, #0

800210a: 681b ldr r3, [r3, #0]

800210c: deff udf #255 ; unknown instruction

800210e: bf00 nop ; instead of branching to printf

What the hell? How do I avoid such an behavior of the compiler. How did the developers of gcc come up with this brilliant solution? So many questions... WHYYYY?? Maybe it indeed makes sense?

Btw, i assigned to variable value of 0 from user input (in runtime, so compiler makes no guesses about value), AND IT WORKED!. I've read the exact first word from binary firmware!

🌐
Quora
quora.com › What-happens-if-you-dereference-a-null-pointer
What happens if you dereference a null pointer? - Quora
Answer (1 of 8): The outcome is exactly the same as with any other pointer. If the address represents a valid mapping for which the attempted action is permitted (typically read, write or execute, as determined by the instruction that attempts the access and/or its context), the address is resol...
🌐
Quora
quora.com › Why-does-C-allow-us-to-dereference-null-pointers-without-throwing-an-exception-at-runtime
Why does C++ allow us to dereference null pointers without throwing an exception at runtime? - Quora
Answer (1 of 2): Question: Why does C++ allow us to dereference null pointers without throwing an exception at runtime? Your premise is false. C and C++ BOTH don’t allow a programmer to dereferenc null pointers. Look here: [code]int *iPtr = 0; *iPtr = 56; [/code]Line 2 will throw a system excep...
🌐
Mayhem Security
mayhem.security › blog › what-is-null-pointer-dereference
What Is Null Pointer Dereference? | Mayhem
June 1, 2022 - Null pointer dereferences are particularly common in C and C++ programs, since these languages do not automatically check for NULL pointers.
🌐
Sivanesh Waran
sivaneshwaran.com › home › klocwork › null pointer dereference in c
Null Pointer Dereference in C Null Pointer Dereference in C
May 5, 2023 - May 3, 2023 / By Sivanesh. Null pointer dereference is a common programming error that occurs when a program attempts to dereference a pointer that points to null or undefined memory.
🌐
Quora
quora.com › Everyone-says-dereferencing-a-null-pointer-is-really-bad-but-what-will-actually-happen-and-why-Im-especially-interested-in-systems-without-paging-as-a-page-fault-would-probably-occour-if-paging-is-present
Everyone says dereferencing a null pointer is really bad, but what will actually happen, and why? (I'm especially interested in systems without paging, as a page fault would probably occour if paging is present) - Quora
Originally Answered: Everyone says dereferencing a null pointer is really bad, but what will actually happen, and why? (I'm especially interesting in systems without paging, as a page fault would probably occour if paging is present) · · It’s important to realize that the null pointer in C and C++ is an abstraction. It compares equal to a null pointer constant. ... [2] That’s the integer literal constant 0, or a literal 0 cast to a pointer type, or in C++11 onward, nullptr...
🌐
SEI CERT
wiki.sei.cmu.edu › confluence › display › c › EXP34-C.+Do+not+dereference+null+pointers
EXP34-C. Do not dereference null pointers | CERT Secure Coding
In this noncompliant code example, input_str is copied into dynamically allocated memory referenced by c_str . If malloc() fails, it returns a null pointer that is assigned to c_str . When c_str is dereferenced in memcpy() , the program exhibits undefined behavior .
🌐
Sonar Community
community.sonarsource.com › sonarqube server / community build
C/C++ False-negative: “Dereference of null pointer (loaded from variable 'xptr')” - SonarQube Server / Community Build - Sonar Community
April 5, 2023 - which versions are you using (SonarQube, Scanner, Plugin, and any relevant extension) Sonarqube Enterprise Edition Version 9.9 (build 65466) how is SonarQube deployed: zip, Docker, Helm Not sure, separate server what are you trying to achieve I want to check if null ptr dereferences are picked ...
🌐
Quora
quora.com › What-actually-happens-when-dereferencing-a-NULL-pointer-Usually-the-process-terminates-Does-the-reaction-depend-on-the-operating-system-or-is-it-controlled-by-the-compiler-Is-it-mandatory-that-NULL-always-be-defined-as-“0”-with-proper-casting
What actually happens when dereferencing a NULL pointer? Usually, the process terminates. Does the reaction depend on the operating syste...
Answer (1 of 10): C/C++ are different from most of the popular languages: there is no runtime environment, there are no runtime checks, the actual machine language instructions will be generated and executed performing the read/write access at address zero. The behavior is entirely HW dependent. ...