繁体   English   中英

绊倒在C ++的非凡布尔场景中

[英]stumbling upon a non-trivial bool scenario in C++

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

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

您的代码结构如此,如果pre 假,则永不访问x的值-我认为在这种情况下,静态分析器没有提供有用的输出。

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

  1. 访问x的第一条语句位于if ( !pre || !x || !post ) -由于短路评估if( A || B || C )不评估BC如果A为真; 因此,我们永远不会尝试读取未初始化的x (因为x仅在pre为false时才被初始化,在这种情况下,我们停止了对表达式的求值!)

  2. 第二种用法是

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

    同样,只有在pre为true的情况下,我们才可以触犯问题(在这种情况下, x已正确初始化)。

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

  1. 即使pre为false,实际代码也会在某些情况下错误地尝试读取x ,并且在构建示例时您会漏掉它(有时程序的逻辑流程可能有点晦涩)

  2. 静态分析器是惰性的,会发现else if( !x ) ,并且无法确定该行是否可以通过未初始化的值访问。

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

如果您不确定或实际逻辑过于晦涩,建议您为x指定一个默认值。

在Cppcheck中是误报 我通过添加一个内联抑制来解决它: [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条件为false ,则x将被初始化。 if ( !x ) CppCheck警告有关不确定值的使用。 要修复它,请初始化x变量。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM