在C ++中遇到一个非平凡的bool场景

时间:2016-08-08 13:03:58

标签: c++ cppcheck false-positive

当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个参数中。

3 个答案:

答案 0 :(得分:1)

静态分析似乎在抱怨,因为如果runMaybeT为false,则永远不会设置pre

您的代码的结构使得x 为假时永远不会访问x的值 - 我认为静态分析器不是&#39;在这种情况下给出一个有用的输出。

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

  1. 访问pre的第一个语句位于x行 - 由于short-circuiting evaluationif ( !pre || !x || !post )并未评估{{1}如果if( A || B || C )为真,则为B;因此,我们永远不会尝试阅读未初始化的C(因为A仅在x为假时未被初始化,在这种情况下我们停止评估表达式!)

  2. 第二种用法是

    x

    同样,如果pre为真,我们只能触及有问题的行(在这种情况下if ( !pre ) { trace("pre failed"); } else if ( !x ) { // <-- HERE Cppcheck complains已正确初始化)。

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

    1. 实际代码在某种情况下错误地尝试阅读pre,即使x为假,在构建示例时您也错过了它(有时是逻辑流程程序可能有点迟钝)

    2. 静态分析器是惰性的并且会找到行x,并且无法确定此行是否可以使用未初始化的值进行访问。

    3. 根据您提供的代码,您不应该担心:静态分析工具在技术上是正确的,pre可以是未初始化的,但在这些情况下它不会被使用(因此可能不应该警告你)。

      如果您不自信,或者实际逻辑非常钝,我建议您为else if( !x )分配一个默认值。

答案 1 :(得分:1)

Cppcheck中的误报。我通过添加内联抑制来解决 [1]

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

我也引起了Cppcheck开发人员的注意:

#7663 (False positive: uninitialised variable in unreachable code)

[1] 我决定不初始化变量。这不是出于性能原因,而是为了了解未来版本中修复的错误,当时Cppcheck会说

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

答案 2 :(得分:0)

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