5

I still can't pinpoint exactly on which level undefined behaviour is actually defined. Assume the following code:

int i = value;
unsigned int x = static_cast<unsigned int>(i);

This is valid C++ code and defined if e.g. i is 1. But on i = -1 it becomes undefined behaviour, so the application is in UB state during runtime.

In the code sample below UB is already apparent during compile time. So my question is, is it correct that UB can be either during compile time or runtime? What is the correct terminology here?

void foo(int* p)
{
    int v = *p;
    if (p == nullptr)
        return;
}
Hagadol
  • 362
  • 1
  • 3
  • 16
Daniel Stephens
  • 2,371
  • 8
  • 34
  • 86
  • 3
    In both cases it's not necessarily UB, only if the statements are actually executed. – aschepler Oct 30 '19 at 14:25
  • 5
    There's no undefined behavior for `i = -1`. Overflow during *arithmetic* leads to undefined behavior. But a cast has a well defined meaning here. – StoryTeller - Unslander Monica Oct 30 '19 at 14:25
  • @aschepler: it is, see post of duDE, it extends to even parsing which quite answers my question – Daniel Stephens Oct 30 '19 at 14:28
  • @StoryTeller-UnslanderMonica That sounds reasonable but latter example actually creates false code by compilers since an optimizer assumes it can never be true so UB must have an impact on compile time – Daniel Stephens Oct 30 '19 at 14:30
  • 1
    OP, you misunderstand. Compile-time UB, also known as "ill-formed NDR", can happen if the condition for the UB to happen involves the program text rather than the program execution. However, run-time UB cannot occur at compile-time because the program has to actually be executed in order to determine whether the run-time evaluation that is UB actually occurs or not. – Brian Bi Oct 30 '19 at 14:31
  • @Brian So latter example is actually NDR, but not UB? Means NDR leads to UB but is not UB – Daniel Stephens Oct 30 '19 at 14:32
  • 1
    The second example is well-formed, and is not guaranteed to cause UB, because it's possible that `foo` will only be called with non-null pointers. – Brian Bi Oct 30 '19 at 14:34
  • 1
    There are some requirements which definitely could be diagnosed at compile time but are still described as UB, not ill-formed (with or without NDR). – aschepler Oct 30 '19 at 14:35
  • I do not understand example 1, casting int a to unsigned int b is defined behavior for all values of a since unsigned integers shall obey the laws of modular arithmetic. – Öö Tiib Oct 30 '19 at 14:54
  • @Öö Tilb the value - 1 cannot be represented by an unsigned int – Daniel Stephens Oct 30 '19 at 15:04
  • 1
    @DanielStephens -- yes, the value -1 cannot be represented by an unsigned int. But the result of **converting** that value to `unsigned int` is well defined. As an earlier comment said, unsigned integers obey the laws of modular arithmetic. So the result is the largest value that an `unsigned int` can hold. – Pete Becker Oct 30 '19 at 15:36

0 Answers0