绊倒在C ++中的非凡布尔场景中 [英] stumbling upon a non-trivial bool scenario in C++

查看:100
本文介绍了绊倒在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;

//错误检查原始代码的通过:
if(!pre ||!x ||!post){
if(!pre){
trace( pre failed);
}否则if(!x){//<-Cppcheck在这里抱怨
trace( x failed);
}否则{
trace( post failed);
}
} else {
//成功通过原始代码:
trace( ok);
}
}

这是一条消息,让我感到紧张:

  Id:uninitvar 
摘要:未初始化变量:x
消息:未初始化变量:x

我认为这是一个误报,但我承认这可能并不明显。不过,我不想修改该代码,因为它比此提取的版本旧且重得多。



您是否遇到过这种情况?如何处理它?<​​/ p>




[1] 这段代码精简了,原始代码建立了前提条件( pre ),做了一些事情( x ),然后强制了后置条件( post ),然后检查一些错误情况。我转换了所调用函数的运行时结果,然后将其存储在 pre x post 放入测试用例的3个参数中。

解决方案

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



您的代码的结构使得如果 pre 为<$>,则永远不会访问 x 的值错误-在这种情况下,我认为静态分析器无法提供有用的输出。



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


  1. 其中 x if(!pre ||!x ||!post)行中-由于短路评估 if(A || B || C)不评估 B C ,如果 A 为真;因此,我们绝不会尝试读取未初始化的 x (因为 x 仅在 pre 为假,在这种情况下,我们停止了对表达式的求值!)


  2. 第二种用法在



    if(!pre){
    trace( pre failed);
    }否则,如果(!x){//<-Cppcheck在这里抱怨



    我们只能再次点击如果 pre 为真(在这种情况下 x 已正确初始化),则违反了代码。


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


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


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


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



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


When Cppcheck runs over this code,[1] it complains about an error:

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");
    }
}

This is the message, that makes me nervous:

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

I think it's a false positive, but I admit that this may not be obvious. Nevertheless I don't want to touch that code, because it's old and a lot heavier than this extracted version.

Have you ever experienced situations like this? How to deal with it?


[1] This code is reduced to its bones, the original code establishes a precondition (pre), does something (x), then forces a postcondition (post), after that, some error conditions are checked. I transformed the runtime-results of the functions that are called and then stored in pre, x, and post into the 3 arguments of my test case.

解决方案

The static analysis appears to be complaining because if pre is false, then x is never set.

Your code is structured such that the value of x is never accessed if pre is false - I'd argue that the static analyser isn't giving a useful output in this case.

Enumerating the various cases we have (so we can be reasonably sure that it's cppcheck and not us!):

  1. The first statement in which x is accessed is in the line if ( !pre || !x || !post ) - due to short-circuiting evaluation: if( A || B || C ) doesn't evaluate B or C if A is true; hence we never try to read an uninitialised x (since x is only uninitialised if pre is false, in which case we stopped evaluated the expression!)

  2. The second usage is in

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

    Again, we can only hit the offending line if pre was true (in which case x is properly initialised).

From this, we can conclude that either:

  1. The actual code mistakenly tries to read x in some condition even is pre is false, and you've missed it when building the example (sometimes the logical flow of a program can be a bit obtuse)

  2. The static analyser is lazy and spots the line else if( !x ) and can't determine if this line is reachable with an uninitialised value.

From the code you've provided, you shouldn't be concerned: the static analysis tool is technically correct that x can be uninitialised, but in those cases it's not used (and hence probably shouldn't be warning you).

I'd recommend assigning x a default value if you're not confident, or if the actual logic is exceedingly obtuse.

这篇关于绊倒在C ++中的非凡布尔场景中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆