Undefined behavior
In computer science , undefined behavior describes code whose behavior is not specified and is therefore treated arbitrarily by various implementations of compilers . This is a property of some programming languages, such as C or C ++ . The semantics of certain operations are not defined in the standards of these languages, which means that an implementation can assume that these operations do not normally occur. As a result, the behavior of the implementation always conforms to the standards of the language. It is the responsibility of the programmer never to write code that triggers undefined behavior, but compiler implementations are allowed to issue diagnoses in this case.
Examples
In C, for example, division by zero leads to undefined behavior:
int f(int x) {
return x/0; // undefiniert
};
Likewise the dereferencing (tracking) of a null pointer :
int* p = NULL;
int i = *p; // undefiniert
Optimization possibilities
If the standard declares an operation to be undefined with certain values, the compiler can assume that the invalid values never occur. The compiler may apply this assumption to the following operations. An example would be dereferencing a pointer. If the pointer were NULL
, it would be undefined behavior.
int get_int(int* p) {
int i = *p; // Dereferenzierung -> p != NULL
if(p == NULL) {
return 42;
};
return i;
}
The complete conditional block may be removed by the compiler because the pointer has already been dereferenced. The compiler assumes that the pointer cannot NULL
be. This can be remedied by, for example, moving access to the referenced memory after the test:
int get_int(int* p) {
// p darf hier alles sein
if(p == NULL) {
return 42;
};
int i = *p; // Dereferenzierung -> p != NULL
return i;
}
The following may also be completely removed:
if(p == NULL) {
int i = *p;
printf("Hello");
}
Subcategories
A distinction is made between undefined operations and undefined values. While reading through a null pointer is an undefined operation (possibly leading to a program crash), reading from uninitialized memory only results in an undefined value. For example, if an unknown value is associated with exclusive or with itself, it is always 0, so the following is completely legal:
int value; // Startwert von value nicht gesetzt
value ^= value; // exklusiv-oder Verknüpfung
// value ist nun definiert als 0
This is similar to counting down to 0 ( int
negative values would be possible, reducing the lowest value that int
can be assumed is an undefined operation):
unsigned value;
while(value != 0) { --value; }
In this way, in the Brainfuck language, a memory cell is set to 0, which is the code for it .
[-]
Individual evidence
- ^ What Every C Programmer Should Know About Undefined Behavior. Retrieved November 16, 2014 .