不可达代码
在执行期间无法到达的代码
描述
此检查用于确定一段代码是否静态不可达。为了确定可达性,此检查会评估决定是否执行一段代码的条件。
如果至少有一个条件的静态评估结果为 true,则认为该段代码可达。
如果所有条件的评估结果始终为 false,则该段代码将显示为不可达代码。
根本不评估或评估结果始终为 true 的条件也显示为不可达代码。
不可达代码的示例包括下列项:
如果
if
条件表达式的评估结果始终为 false,则无法到达相应的代码分支。在源窗格中,该分支的左大括号显示为灰色。如果
if
条件表达式的评估结果始终为 true,则该条件是冗余的。在源窗格中,if
关键字显示为灰色。跟在
break
或return
语句后的代码。
如果某个代码块的左大括号在源窗格中显示为灰色,要突出显示整个块,请双击该大括号。
检查操作的对象是函数内的代码。未调用函数和不可达函数检查将确定是否函数本身未被调用,或者是从不可达代码内调用的。
示例
if
语句中的测试结果始终为 False
#define True 1
#define False 0
typedef enum {
Intermediate, End, Wait, Init
} enumState;
enumState input();
enumState inputRef();
void operation(enumState, int);
int checkInit (enumState stateval) {
if (stateval == Init)
return True;
return False;
}
int checkWait (enumState stateval) {
if (stateval == Wait)
return True;
return False;
}
void main() {
enumState myState = input(),refState = inputRef() ;
if(checkInit(myState)){
if(checkWait(myState)) {
operation(myState,checkInit(refState));
} else {
operation(myState,checkWait(refState));
}
}
}
在此示例中,只有当 myState = Init
时,main
才会进入 if(checkInit(myState))
分支。因此,在该分支内,Polyspace® 会认为 myState
具有值 Init
。checkWait(myState)
始终返回 False
并且 if(checkWait(myState))
的第一个分支是不可达的。
一种可能的更正方法是删除冗余测试 if(checkWait(myState))
。
#define True 1 #define False 0 typedef enum { Intermediate, End, Wait, Init } enumState; enumState input(); enumState inputRef(); void operation(enumState, int); int checkInit (enumState stateval) { if (stateval == Init) return True; return False; } int checkWait (enumState stateval) { if (stateval == Wait) return True; return False; } void main() { enumState myState = input(),refState = inputRef() ; if(checkInit(myState)) operation(myState,checkWait(refState)); }
if
语句中的测试结果始终为 True
#include <stdlib.h>
#include <time.h>
int roll() {
return(rand()%6+1);
}
void operation(int);
void main() {
srand(time(NULL));
int die = roll();
if(die >= 1 && die <= 6)
/*Unreachable code*/
operation(die);
}
在此示例中,roll()
返回一个介于 1 到 6 之间的值。因此,main
中的 if
测试的计算结果始终为 true,是冗余的。如果有一个对应的 else
分支,则 else
语句上会显示灰色错误。如果没有 else
分支,则 if
关键字上会显示灰色错误来指示冗余情况。
一种可能的更正方法是删除 if(die >= 1 && die <=6)
条件。
#include <stdlib.h> #include <time.h> int roll() { return(rand()%6+1); } void operation(int); void main() { srand(time(NULL)); int die = roll(); operation(die); }
if
语句中的测试不可达
#include <stdlib.h> #include <time.h> #define True 1 #define False 0 int roll1() { return(rand()%6+1); } int roll2(); void operation(int,int); void main() { srand(time(NULL)); int die1 = roll1(),die2=roll2(); if((die1>=1 && die1<=6) || (die2>=1 && die2 <=6)) /*Unreachable code*/ operation(die1,die2); }
在此示例中,roll1()
返回一个介于 1 到 6 之间的值。因此,if
测试的第一部分 if((die1>=1) && (die1<=6))
始终为 true。因为 if
测试的两个部分通过 ||
组合在一起,所以不管第二部分如何,if
测试始终为 true。因此,if
测试的第二部分不可达。
&&
来组合测试一种可能的更正方法是使用 &&
来组合 if
测试的两个部分,而非使用 ||
。
#include <stdlib.h> #include <time.h> #define True 1 #define False 0 int roll1() { return(rand()%6+1); } int roll2(); void operation(int,int); void main() { srand(time(NULL)); int die1 = roll1(),die2=roll2(); if((die1>=1 && die1<=6) && (die2>=1 && die2<=6)) operation(die1,die2); }
if
语句因为前面的变量关系而不可达
typedef enum {init, run, completion} states;
int getAnInput();
states a = init;
void f(int b)
{
switch (a) {
case init: {
if (b == 3) {
a = completion;
}
break;
}
case completion: {
if (b == 1) { //Unreachable code
//....
}
break;
}
//...
}
}
void main()
{
int b = getAnInput();
f(b);
f(b);
}
有时候,某个代码块可能因为变量值受代码中前面的运算约束而不可达。如果您不理解为什么某个条件始终为 true 或 false,请查看条件中的变量是否因为前面的某个运算而受到约束。
在此示例中,函数 getAnInput()
已上桩,因为未提供它的定义。通过 getAnInput()
初始化的变量 b
可以接受 int 数据类型允许的任何值。在 f()
调用中,b
看起来可以具有包括值 1 和 3 在内的任何值。不过,条件 (b == 1)
似乎为 false,对应的代码块不可达。
请观察两个 f()
调用。在第一个 f()
调用中,switch 语句选择 case init
。在 case init
中,b
可以是完整范围。如果 b
等于 3,则 a
被设置为 completion。第二次调用 f()
函数时,switch 语句可以选择 case init
或 case completion
。因为可以选择 case completion
的唯一途径是当 b
先前等于 3 时,并且因为在 case init
外部没有对 b
进行操作,因此 Polyspace 假定 b
仍然等于 3。因此,if 语句条件 (b == 1)
永远不会得到满足,这导致 case completion
中出现不可达代码。
switch
语句中的不可达 case
子句
void test1 (int a)
{
int tmp = 0;
if ((a!=3))
{
switch (a)
{
case 1:
tmp++;
break;
default:
tmp = 1;
break;
/* case 3 falls through to
case 2, no dead code */
case 3:
case 2:
tmp = 100;
break;
}
}
}
void test2 (int a)
{
int tmp = 0;
if ((a!=3))
{
switch (a)
{
case 1:
tmp++;
break;
default:
tmp = 1;
break;
// Dead code on case 3
case 3:
break;
case 2:
tmp = 100;
break;
}
}
}
在此示例中,switch
语句的 case 3
在函数 test1()
和 test2()
中不可达。
在
test1()
中,case 3
将穿透执行到case 2
,并且检查结果显示没有死代码。在
test2()
中,检查结果显示case 3
存在死代码,因为下一行中的break
语句未执行。
检查信息
组:数据流 |
语言:C | C++ |
缩写: UNR |
版本历史记录
R2023b: 检查会跳过 if constexpr
语句
在查找不可达代码时,检查会跳过 if constexpr
语句。
MATLAB 命令
您点击的链接对应于以下 MATLAB 命令:
请在 MATLAB 命令行窗口中直接输入以执行命令。Web 浏览器不支持 MATLAB 命令。
Select a Web Site
Choose a web site to get translated content where available and see local events and offers. Based on your location, we recommend that you select: .
You can also select a web site from the following list:
How to Get Best Site Performance
Select the China site (in Chinese or English) for best site performance. Other MathWorks country sites are not optimized for visits from your location.
Americas
- América Latina (Español)
- Canada (English)
- United States (English)
Europe
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom (English)