Undefined behavior (UB) is actions in the code whose behavior is not defined by the standard. In such cases, the compiler is free to make any decisions: the program may behave differently on different platforms, compilers, or even launch a nuclear war (formally!). Using UB is the most dangerous mistake in C++.
Examples of UB:
int* p = new int[2]; delete[] p; int x = p[1]; // UB: accessing memory after it has been freed
To prevent UB:
What will happen with the following code?
int a = 42; int b = a++ + ++a;What will be the value of
b?
Answer:
This code causes UB because it modifies and reads the variable a without a sequence of points (sequence points) between operations. The standard does not guarantee a specific result, and the compiler may produce any result or even generate unexpected code.
Story In a data storage system project, one of the developers caused an array out-of-bounds in a low-level function. UB manifested only with certain user data and led to file structure corruption and loss of client data.
Story In a microcontroller project, there were constructs with reading uninitialized variables. The tests passed, but a year after the device was released, random errors in operation appeared due to UB: variables sometimes contained garbage values.
Story In a large open-source project, a descriptor was found being freed twice from different parts of the code. This UB manifested very rarely at first, but in new OS versions, it began to lead to frequent crashes.