在c++中偶然发现了一个重要的bool场景

stumbling upon a non-trivial bool scenario in C++

本文关键字:一个 重要的 场景 bool c++ 偶然 发现      更新时间:2023-10-16

当Cppcheck运行此代码时,[1]会报错:

void bool_express(bool aPre, bool aX, bool aPost)
{
    bool x;
    const bool pre = aPre;
    if (pre) {
        x = aX;
    }
    const bool post = aPost;
    // error checking passage of the original code:
    if ( !pre || !x || !post ) {
        if ( !pre ) {
            trace("pre failed");
        } else if ( !x ) {       // <-- HERE Cppcheck complains
            trace("x failed");
        } else {
            trace("post failed");
        }
    } else {
        // success passage of the original code:
        trace("ok");
    }
}

这就是让我紧张的消息:

Id: uninitvar
Summary: Uninitialized variable: x
Message: Uninitialized variable: x

我认为这是一个假阳性,但我承认这可能不明显。然而,我不想碰那些代码,因为它是旧的,而且比这个提取的版本重得多。

你经历过这样的情况吗?如何处理?


[1]这段代码被简化为它的骨架,原始代码建立一个先决条件(pre),做一些事情(x),然后强制一个后置条件(post),之后,检查一些错误条件。我将调用并存储在prexpost中的函数的运行时结果转换为测试用例的3个参数。

在Cppcheck中为假阳性。I 通过添加内联抑制来解决问题:[1]

    if ( !pre ) {
        trace("pre failed");
    // cppcheck-suppress uninitvar
    } else if ( !x ) {
        trace("x failed");
    } else {
        trace("post failed");
    }

,我也提请Cppcheck开发人员注意:

#7663(误报:不可达代码中未初始化的变量)


[1]我决定不初始化变量。这不是出于性能原因,而是为了在将来的版本中获知该错误正在修复,届时Cppcheck将显示

Id: unmatchedSuppression
Summary: Unmatched suppression: uninitvar
Message: Unmatched suppression: uninitvar

静态分析似乎在抱怨,因为如果pre为假,那么x永远不会设置。

你的代码结构使得x的值永远不会被访问,如果pre false -我认为静态分析器在这种情况下没有给出有用的输出。

列举我们拥有的各种情况(因此我们可以合理地确定它是cppcheck而不是我们!):

  1. 第一个访问x的语句在if ( !pre || !x || !post )行-由于短路求值:如果A为真,if( A || B || C )不求BC;因此,我们从不尝试读取未初始化的x(因为x只有在pre为false时才未初始化,在这种情况下,我们停止对表达式求值!)

  2. 第二个用法在

    if ( !pre ) { trace("pre failed"); } else if ( !x ) { // <-- HERE Cppcheck complains

    同样,只有当pre为true时(在这种情况下,x被正确初始化),我们才能击中违规行。

由此,我们可以得出结论:

  1. 实际代码在某些情况下错误地试图读取x,即使pre是假的,并且在构建示例时您已经错过了它(有时程序的逻辑流可能有点迟钝)

  2. 静态分析器是惰性的,它发现else if( !x )行,并且不能确定该行是否具有未初始化的值。

从你提供的代码来看,你不应该担心:静态分析工具在技术上是正确的,x可以被未初始化,但在那些情况下,它不被使用(因此可能不应该警告你)。

我建议给x分配一个默认值,如果你不自信,或者如果实际的逻辑是非常迟钝的。

如果您的pre条件为false,则x将未初始化。在if ( !x )行,CppCheck警告使用不确定的值。要修复它,请初始化x变量