Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Testing Undefined Behavior

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.

like image 262
MooseBoys Avatar asked Sep 16 '19 19:09

MooseBoys


People also ask

How do you check for undefined behavior in C++?

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.

What causes 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.

Is unspecified behavior undefined behavior?

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.

What does undefined behavior mean in C?

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.


2 Answers

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.

like image 123
Daniel Langr Avatar answered Sep 29 '22 22:09

Daniel Langr


Your reasoning is sound and it is indeed not possible to test for undefined behaviour within the confines of the C++ language.

like image 40
eerorika Avatar answered Sep 29 '22 22:09

eerorika