Is it possible, within the confines of only the C++ language, to write a test that isolates and detects undefined behavior when executed? For example, given the following code:
void fn(int* p) {
int x = *p;
}
void foo() {
int x = 42;
fn(&x);
}
void bar() {
fn(nullptr);
}
Is it possible to construct a test that invokes foo
and bar
, and "passes" for foo
but "fails" for bar
? My assumption is that it is not possible because the very act of invoking bar
means the compiler is free to generate code that always passes, always fails, only fails on Tuesdays, or just prints "thanks for all the fish" in an endless loop. Still I'd like to get confirmation from the experts that this is the case.
Note: I'm aware of things like clang's ubsan, static analysis tools, and platform-specific traps to assist with detection of UB, but my question is limited to the C++ language only.
However, it is possible to determine whether a specific execution of a C++ produced undefined behavior. One way to do this would be to make a C++ interpreter that steps through the code according to the definitions set out in the spec, at each point determining whether or not the code has undefined behavior.
In computer programming, undefined behavior (UB) is the result of executing a program whose behavior is prescribed to be unpredictable, in the language specification to which the computer code adheres.
Unspecified behavior is different from undefined behavior. The latter is typically a result of an erroneous program construct or data, and no requirements are placed on the translation or execution of such constructs.
When we run a code, sometimes we see absurd results instead of expected output. So, in C/C++ programming, undefined behavior means when the program fails to compile, or it may execute incorrectly, either crashes or generates incorrect results, or when it may fortuitously do exactly what the programmer intended.
Undefined behavior is defined as a behavior for which the C++ Standard imposes no requirements. This basically means that the defined behavior is imposed by the requirements from the Standard.
You can never tell whether some behavior is defined or undefined just by observing that behavior (in both cases, the observable behavior may be the very same). You may only want to check whether all the requirements from the Standard have been met. However, such check is generally infeasible.
Consider your simple example. You can check p
for null pointer, but, if it's not null, there is no way to tell whether it actually does or does not point to a valid object of type int
. It might be possible in your simple program, provided it's compiled as a standalone translation unit, but generally it is not.
Your reasoning is sound and it is indeed not possible to test for undefined behaviour within the confines of the C++ language.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With