了解未定义行为的范围

时间:2018-03-22 17:49:32

标签: c++ undefined-behavior

C ++标准以什么方式(如果有的话)限制了未定义行为的影响?例如,在下面的代码中,从第一个if检查undefined是控制流被约束为遵循then路径或else路径?允许跳过这两条路径吗?执行两个路径(可能并行)?在第二个if的中间跳一个狂野的跳跃?

void f(int undefined) {
    bool startNuclearWar = true;

    if (undefined > 0) {
        printf("True path\n");
        startNuclearWar = false;
    } else {
        printf("False path\n");
        startNuclearWar = false;
    }

    if (startNuclearWar) {
        lauchMissles();
    }
}

3 个答案:

答案 0 :(得分:2)

该标准对UB没有限制。当您执行任何调用UB的那一刻时,该标准不保证会发生什么。

答案 1 :(得分:0)

虽然在很多情况下能够“划分”未定义的行为是有用的,并且虽然这样做在许多平台上都很便宜,但是编写标准的人并没有表现出这样做的任何重大兴趣。 C11标准提供了附件L关于“可分析性”的内容,但如果定义__STDC_ANALYZABLE__,则无法描述实施必须保证的任何有意义的内容。

例如,整数溢出是有界未定义行为的事实将是有限的使用,如果没有一种方法来确保代码如下所示:

 int index = computeSomething();
 if (index < 0 || index >= ARRAYSIZE) FatalError();
 myArray[index]++;

将在比较和数组查找中使用index的相同值。

许多实现可以廉价地提供超出标准所要求的许多有用的保证,特别是在应用程序字段中,如果程序在给定无效输入时异常终止是可接受的,但是不允许它允许恶意构造的输入控制机器。遗憾的是,标准未能提供必要的钩子以有效地利用它(例如,提供一个内在的,它将采用可能不确定的值并产生最坏的值未指定)。在执行比较之前,在上面的代码中对index中的值应用这样的内在函数将确保即使在computeSomething中发生溢出,代码也可以保证在数组中增加一个值,或者请注意index无效。由于这两种操作都不会导致严重的未定义行为,因此执行将保持在轨道上。

答案 2 :(得分:0)

  

以什么方式(如果有的话),C ++标准是否限制了未定义行为的影响?

无论如何。未定义的行为本质上是 undefined ,因此绝对任何都可能发生。一旦 undefined 发生了什么事,该程序的状态从那时起就是 unknown

话虽如此,您所显示的代码中没有未定义的行为。代码中的所有内容都定义了行为。

  

例如,在下面的代码中,从第一个if检查undefined开始,控制流是否被约束为遵循then路径或else路径?

  

是否可以跳过这两条路径?

没有

  

执行两条路径(可能并行)?

没有

  

在第二个中间跳一个狂野的跳跃?

没有