Undefined Behavior (UB) is a situation where the language standard does not define the behavior of a program. The compiler can do anything with the program: it can crash, produce incorrect results, or even 'work'. UB arises from errors such as array out-of-bounds access, dereferencing a null pointer, etc.
int arr[5]; arr[10] = 42; // UB: out-of-bounds access int* p = nullptr; *p = 1; // UB: dereferencing 0
Avoiding UB can be achieved by adhering to standards, using modern tools (ASan, UBSan, valgrind), trying not to use raw pointers, and writing safe code.
If UB occurs in one part of the program, can it affect a completely different, 'independent' part of the code?
Yes! The compiler during optimization may make unexpected transformations if it detects UB.
void foo(int* p) { if (p == nullptr) return; *p = 5; // But if p was not nullptr, this is UB! But the compiler may remove checks, assuming that p is always valid. }
Story
On the server of a large company, random crashes of the process occurred from time to time due to dereferencing a null pointer, which were hard to reproduce: it worked in debug mode, but not in release mode.
Story
When porting code from 32-bit to 64-bit, data types got mixed up, and cast between int and pointer was used. It worked on some machines while other machines experienced crashes and strange artifacts.
Story
An infamous case on the internet involved harmless UB (out-of-bounds access) breaking the functionality of the entire program: the compiler removed not only the interaction with the array but also 'optimized' a part of the code that was not related to the error.