web-dev-qa-db-ja.com

到達不能コード:エラーまたは警告?

これは言語設計の質問です:

到達不能コード(一般的なプログラミング言語)は警告(つまり「問題を報告してとにかくコンパイルする」)またはエラーを発生させるべきだと思いますか(「コンパイルを拒否する」)?

個人的には、それはエラーであるべきだと強く感じています。プログラマーがコードを書く場合、それは常にsomeで実際に実行することを意図している必要があります。シナリオ。しかし、たとえばC#コンパイラはこれに同意しないようで、警告を報告するだけです。

注:適切なデッドコードの検出は非常に難しい問題であると認識していますが、それはこの質問の焦点では​​ありません。

一部のステートメントが明らかに到達できないコードの例を次に示します。

return;
foo();

-

throw new Exception();
foo();

-

if (...) {
  return;
} else {
  throw new Exception();
}
foo();
22
Martijn

一般的に言えば、それはエラーであるはずです。

ただし、1つの例外が頭に浮かびます。

if (false) {
  doStuffThatITemporarilyDisabled();
}

一部の開発者は、コンパイラがそのようなコードのコンパイルを拒否すると文句を言うかもしれません。

14
Joachim Sauer

エラーは、コンパイラがコードを物理的に処理できないことを意味します。

警告は、コンパイラがコードを処理できることを意味しますが、あなたが書いたものが何らかの形で間違っていると信じています。

それは私にはかなり明確に思えます-それは警告であるはずです。

さらに、デバッグの目的でメソッドを短縮することにした場合はどうでしょうか。

public bool ShowMenu()
{
    return true;
    /* The standard implementation goes here */
}

私はそれが間違っていることを知っていますが、コンパイラーが私にそのコードもコメントアウトするように頼むのは苦痛です。

31
Justin

デバッグ時にデッドコードを意図的に作成することは非常に一般的です。これを防ぐコンパイラは、ユーザーに人気がない可能性があります。

25
anon

警告は適切だと思います。次に、ユーザーは、リリースビルドを実行するときに、「すべての警告をエラーとして扱う」というOTHERスイッチを使用することを決定できます。開発者に権限を与えることは、本質的にランダムな選択を開発者に強制するよりも常に優れています。

警告だと思います。

一般的に言えば、一般的なルールは '警告をエラーとして扱う必要がある'です。到達不能コードを意図せずに記述した場合、警告に表示され、とにかく修正されます。

ただし、Neilが言うように、デバッグ目的などの理由で、意図的にデッドコードを作成することがあります。コンパイラが私にそうさせないのなら、私は本当に、本当にそれを嫌います。

8
Razzie

言語を指定する場合:

  • デッドコードをエラーと見なします
  • Cスタイルの「テキストレベル」の前処理をサポートしていません
  • 行スタイルのコメントとネストできるブロックスタイルのコメントがない

...それなら本当にひどいです。大きなコードブロックをファイルから物理的に切り取ることなく無効にできることが不可欠です。

4
unwind

私は(おそらく)到達不能コードが警告または通知(警告のように、否定的な意味合いがない場合のみ)を生成することを望んでいます。これは主に、自動コード生成が少し簡単になるためです。

3
Vatine

答えは、到達不能コードがエラーまたは警告をトリガーするかどうかに関する最終決定は、開発者の手に委ねられるべきであるということです。コンパイラはどちらかを許可する必要があります。

製品リリースコードの場合、バランスはそれがエラーであることを支持します。本番プログラムに到達不能コードを含めることはできません。

コードのデバッグ/テストの場合、バランスはそれが警告であることを支持します。デバッグまたはテストのためにコードの一部を無効にできると非常に便利です。

上記は、手書きのコードのみを対象としています。自動化されたツールによって生成されたコードの場合、バランスはそれが警告であるか無視されることを支持します。到達不能な部分を含むコードの生成は、特に悪影響を与えることはなく、回避するのが非常に難しい場合があります。

2
david.pfx

そのコードを使用する正当な理由は、開発段階にあることです。特定のコードを一時的に無効にしたいが、それでもこのコードの構文をチェックしたい。

例えば:

int i = 2, j = 3;
int result = 0;

// FIXME: Commented out for now because I have to recheck calculation
if (false) {
  result = i*2+j+3+i*j;
}

System.out.println("Result of difficult calculation = "+result);

リストを置くと「結果= i * 2 + j + 3 + ij;」 /コメント* /の場合、特定の変数(iなど)を削除または名前変更すると、確実に実行されます。エラーは発生しません。

2
Roalt

Javaがデッドコードをエラーとして実装している理由はまだわかりません。プリプロセッサを備えたCとObjective-Cを使用しているため、プリプロセッサディレクティブを簡単に使用して有効化(またはマスク)できます。次のような関数/メソッド:

// C code
#define ENABLE_FOO //Comment off this to turn off foo(void);
int foo(void)
{
#ifdef ENABLE_FOO
    // Do actual stuff.
    int returnVaue = 2;
    // ...
    return returnValue;
#else
    return 0; // Turned off
#endif
}
// Compiling using clang, enforcing dead code detection:
// clang main.c -Wall -Werror

または、Objective-Cのように、リフレクションを利用できます。

// Class
#define MYCLASS_ENABLE_FOO // Comment off to enable -[MyClass foo]
@interface MyClass : NSObject
#ifdef MYCLASS_ENABLE_FOO
- (int)foo;
#endif
@end
// The like is done in implementation.
// Invoking:
int main(int argc, char **argv)
{
    MyClass *object = [[MyClass alloc] init];
    int value = ([object respondsToSelector:@selector(foo)]) ? // Introspection.
                [object foo] : 0;
    printf("Value: %d", value);
    return 0;
}
2
Maxthon Chan

デフォルトでは、エラーとして処理できるようにするコンパイラフラグが付いた警告である必要があります。 必須どちらか一方が変更できないことは考慮されていません。

2
plinth

Roaltが言ったのと同じ理由でそれは警告であるべきだと思います。優れたコンパイラは、このコードをコンパイルから除外する必要もあります。

2
eWolf