到達不能コード
コードが実行中に到達できません。
説明
このチェックでは、コード セクションが静的に到達不能であるかどうかが判別されます。到達可能性を判別するために、コード セクションが実行されるかどうかを判定する条件を評価します。
少なくとも 1 つの条件が静的に true と評価された場合、そのコード セクションは到達可能とみなされます。
すべての条件が常に false に評価される場合、そのコード セクションは到達不能コードとして表示されます。
まったく評価されない条件、または常に true に評価される条件も、到達不能コードとして表示されます。
到達不能コードの例には以下があります。
if
条件式が常に false に評価される場合、対応するコード分岐には到達できません。[ソース] ペインで、分岐の左中かっこはグレーになります。if
条件式が常に true に評価される場合、この条件は冗長です。[ソース] ペインでif
キーワードがグレー表示されます。コードの前に
break
またはreturn
ステートメントがある。
[ソース] ペインでコード ブロックの左中かっこがグレーで表示される場合、ブロック全体を強調表示するには、中かっこをダブルクリックします。
チェックは関数内のコードで動作します。[呼び出されていない関数] および[到達不能な関数] のチェックにより、関数自体が呼び出されていないか、もしくは到達不能コードから呼び出されているかが判定されます。
このチェックの診断
例
#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));
}
}
}
この例では、main
が if(checkInit(myState))
の分岐に入るのは myState = Init
の場合のみです。したがって、分岐内で Polyspace® は myState
には値 Init
が含まれるとみなします。checkWait(myState)
は常に False
を返し、if(checkWait(myState))
の第 1 の分岐は到達不能です。
1 つの修正方法として、冗長なテスト 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)); }
#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
キーワード上に表示されて、冗長状況を示します。
1 つの修正方法として、条件 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); }
#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
テストの 2 つの部分は ||
で結合されているため、if
テストは、2 番目の部分に関わりなく常に true になります。したがって、if
テストの 2 番目の部分は到達不能です。
&&
で結合1 つの修正方法として、||
ではなく &&
によって if
テストの 2 つの部分を結合するとします。
#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); }
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()
の 2 つの呼び出しを調べてみます。f()
の最初の呼び出しでは、switch ステートメントで case init
が選択されます。case init
内では、b
は全範囲を取ることができます。b
が 3 に等しい場合、a
は completion に設定されます。関数 f()
の 2 回目の呼び出しでは、switch ステートメントでは case init
または case completion
のいずれかを選択できます。case completion
が選択されるのは b
が以前に 3 に等しかった場合であり、case init
の外側で b
が操作されることはないため、Polyspace は b
がまだ 3 に等しいと仮定します。したがって、if ステートメントの条件 (b == 1)
は満たされることがないため、case completion
内に到達不能コードが生じます。
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()
では、次の行のbreak
ステートメントが実行されないため、チェックではcase 3
のデッド コードが示されます。
チェック情報
グループ: データ フロー |
言語: C | C++ |
頭字語: UNR |
バージョン履歴
チェックでは、到達不能コードを探す際に、if constexpr
ステートメントをスキップします。
MATLAB Command
You clicked a link that corresponds to this MATLAB command:
Run the command by entering it in the MATLAB Command Window. Web browsers do not support MATLAB commands.
Web サイトの選択
Web サイトを選択すると、翻訳されたコンテンツにアクセスし、地域のイベントやサービスを確認できます。現在の位置情報に基づき、次のサイトの選択を推奨します:
また、以下のリストから Web サイトを選択することもできます。
最適なサイトパフォーマンスの取得方法
中国のサイト (中国語または英語) を選択することで、最適なサイトパフォーマンスが得られます。その他の国の MathWorks のサイトは、お客様の地域からのアクセスが最適化されていません。
南北アメリカ
- América Latina (Español)
- Canada (English)
- United States (English)
ヨーロッパ
- 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)