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

空扰寡人 提交于 2020-01-05 04:27:10

问题


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.


回答1:


It is a false positive in Cppcheck. I solved it by adding an inline suppression:[1]

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

and I also brought it to the attention of the Cppcheck developers:

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


[1] I decided not to initialize the variable. This is not for performance reasons, but to be informed about the bug being fixed in a future release, when Cppcheck will say

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



回答2:


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.




回答3:


If your pre condition is false than x will be uninitialized. At line if ( !x ) CppCheck warns about usage of indeterminate value. To fix it initialize x variable.



来源:https://stackoverflow.com/questions/38829964/stumbling-upon-a-non-trivial-bool-scenario-in-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!