[英]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
),然后检查一些错误条件。 我转换了被调用函数的运行时结果,然后将其存储在pre
, x
和post
到测试用例的3个参数中。
静态分析似乎在抱怨,因为如果pre
为假,则永远不会设置x
。
您的代码结构如此,如果pre
为假,则永不访问x
的值-我认为在这种情况下,静态分析器没有提供有用的输出。
列举我们遇到的各种情况(因此我们可以合理地确定它是cppcheck而不是我们!):
访问x
的第一条语句位于if ( !pre || !x || !post )
-由于短路评估 : if( A || B || C )
不评估B
或C
如果A
为真; 因此,我们永远不会尝试读取未初始化的x
(因为x
仅在pre
为false时才被初始化,在这种情况下,我们停止了对表达式的求值!)
第二种用法是
if ( !pre ) { trace("pre failed"); } else if ( !x ) { // <-- HERE Cppcheck complains
同样,只有在pre
为true的情况下,我们才可以触犯问题(在这种情况下, x
已正确初始化)。
由此,我们可以得出以下结论:
即使pre
为false,实际代码也会在某些情况下错误地尝试读取x
,并且在构建示例时您会漏掉它(有时程序的逻辑流程可能有点晦涩)
静态分析器是惰性的,会发现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开发人员的注意:
[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.