【初心者向け】C言語の「到達不能コード」とは?サンプルコードで分かりやすく解説


void example() {
  if (true) {
    // このコードは実行される
    printf("Hello world!\n");
  } else {
    // このコードは**絶対に実行されない**
    printf("This code is unreachable.\n");
  }
}

この例では、trueという条件式は常に真に評価されるため、elseブロック内のコードは決して実行されません。 このように、プログラムの実行フローによっては、特定のコードが実行されない状況が発生します。 これが「到達不能コード」と呼ばれるものです。

到達不能コードは、主に以下の2つの理由で問題となります。

  1. プログラムの理解と保守性を低下させる: 到達不能コードは、プログラムの流れを把握しにくくし、メンテナンスを困難にします。
  2. 潜在的なバグの温床となる: 到達不能コードは、意図せぬ論理エラーやバグの隠れ場所となる可能性があります。

到達不能コードの検出と削除

到達不能コードは、静的解析ツールやコンパイラによって検出することができます。 多くの静的解析ツールでは、到達不能コードを警告またはエラーとして報告し、プログラマーが修正することができます。

また、コンパイラによっては、到達不能コードを自動的に削除する最適化機能が備わっているものもあります。

到達不能コードを回避するには、以下の点に注意する必要があります。

  • コードレビューを実施する: コードレビューを実施することで、到達不能コードを含む潜在的な問題を発見することができます。
  • 不要な条件分岐を避ける: 不要な条件分岐は、到達不能コードの原因となる可能性があります。 条件分岐が必要かどうかを慎重に検討しましょう。
  • 論理フローを明確に記述する: コードの論理フローが明確であれば、到達不能コードが発生する可能性を低減することができます。


例1: if 文による到達不能コード

void example1() {
  int x = 10;

  if (x > 20) {
    printf("x is greater than 20.\n");
  } else {
    printf("x is less than or equal to 20.\n"); // このコードは実行されない
  }

  printf("x is %d.\n", x);
}

この例では、x は常に10に初期化されるため、if 文の条件式 x > 20 は常に偽となり、else ブロック内のコードは決して実行されません

例2: switch 文による到達不能コード

void example2() {
  char ch = 'A';

  switch (ch) {
    case 'A':
      printf("ch is A.\n");
      break;
    case 'B':
      printf("ch is B.\n");
      break;
    default:
      printf("ch is not A or B.\n"); // このコードは実行されない
  }

  printf("ch is %c.\n", ch);
}

この例では、ch は常に 'A' に初期化されるため、switch 文で default ケースが選択されることは決してありません

例3: goto 文による到達不能コード

void example3() {
  goto label2;

  printf("This code is unreachable.\n"); // このコードは実行されない

  label1:
    printf("label1.\n");

  label2:
    printf("label2.\n");
}

この例では、goto label2; によって、プログラムの実行フローが直接 label2 に移行するため、その後のコード printf("This code is unreachable.\n");決して実行されません

void example4() {
  int i = 0;

  while (i < 10) {
    printf("i is %d.\n", i++);

    if (i > 5) {
      // このコードは実行されない
      printf("i is greater than 5.\n");
      break;
    }
  }

  printf("i is %d.\n", i);
}

この例では、while ループの条件式 i < 10 は常に真となるため、ループは無限に繰り返されます。 ループ内にある if 文の条件式 i > 5 は、ある時点で真となり break 文を実行してループを抜けますが、それまでに printf("i is greater than 5.\n");決して実行されません



ネットワーク関連

  • 遮断されている: 故意にアクセスできないように設定されている場合
  • 不通: 電話回線や通信路が利用できない場合
  • 使用できない: 特定のサービスや機能が利用できない場合
  • アクセスできない: 特定のWebサイトやサーバーにアクセスできない場合
  • 接続できない: 端末やネットワーク機器に接続できない場合

:

  • インターネット回線が不通のため、オンラインゲームをプレイできません
  • ファイアウォールによって、そのWebサイトへのアクセスは遮断されています
  • サーバーがダウンしているため、Webサイトに接続できません

プログラミング関連

  • 処理されない: 特定のイベントや入力データが処理されない場合
  • 使用されない: 特定の変数や定数が使用されない場合
  • 呼び出されない: 特定の関数やメソッドが呼び出されない場合
  • 実行されない: 特定のコードが実行フローから除外されている場合

:

  • この変数は使用されないため、宣言を削除できます。
  • この関数は呼び出されないため、別の方法で処理する必要があります。
  • このコードは実行されないため、削除しても問題ありません。
  • 行方不明: 特定の人物の所在が不明で連絡が取れない場合
  • 不在: 特定の人物が不在で連絡が取れない場合
  • 利用できない: 特定の施設やサービスを利用できない場合
  • 入手できない: 特定の情報やリソースを入手できない場合

:

  • 彼女は行方不明で、警察が行方を探しています。
  • 彼は会議中なので、不在です。
  • このプールは現在利用できません
  • その本は絶版で、入手できません
  • 否定表現だけでなく、「利用可能」、「アクセス可能」、「実行可能」などの肯定表現も状況に応じて使用することができます。
  • よりカジュアルな表現として、「届かない」、「つながらない」、「使えない」などを使用することができます。
  • よりフォーマルな表現として、「アクセス不能」、「利用不可」、「処理不能」などを使用することができます。