web-dev-qa-db-ja.com

なぜ未使用の変数がそのような問題なのですか?

ある日、未使用の変数の警告を消去していましたが、熟考し始めました。それらの問題は何ですか?

実際、それらの一部はデバッグにも役立ちます(例:例外の詳細を調べる、または返される前に戻り値を確認する)。

実際の実績を見つけることができませんでした。

次のような他のプログラマーの注意を引く時間がかかる行を意味するのではありません。

int abc = 7;

これは明らかな冗長性と注意散漫です。私は次のようなものを意味します:

try {
    SomeMethod();
} catch (SomeException e) {
    // here e is unused, but during debug we can inspect exception details
    DoSomethingAboutIt();
}
9
Tar

あなたが与えたフレームによると、それ自体それら変数に対して議論するのは難しいです:

try {
    SomeMethod();
} catch (SomeException e) {
// here e is unused, but during debug we can inspect exception details
DoSomethingAboutIt();
}

これを例にとります。あなたは例外をキャッチしていて、(おそらく)適切な方法で例外を処理するコードを持っています。例外の実際のインスタンスを使用していないという事実は、コードフローにも理解可能性にも害を及ぼしません。

しかし、私が考えるのは、「未使用の変数」の合法性について書くときです

実際、それらのいくつかはデバッグにも役立ちます

それはコードを書く目的ではなく、後でデバッグする必要があります。誤解を防ぐために、私はよく知っていることを言わなければなりません。多くの場合、コードをfixする必要があります。そして時々debuggingが解決策です。しかし、コードを作成するときに、「アンカーポイント」を残すのは最初のことではありません。その目的は、デバッグを容易にすることだけです。

SomeClass Func() {
    // ...stuff...
    var ret = FinalComputationResult(thing, foo, bar);
    // ret is unused, but while debugging allows checking return value.
    return ret;
}

ここでは、stuffがどの程度複雑であり、それが返される値とどのように関連しているかによって異なります。

「ゴールデンルール」として、私は次のように言います。

コードの目的を理解するのに役立つ場合は、コードに冗長性を持たせても問題ありません

またはそれ以外の場合:

後で簡単に理解するために必要な冗長性なしでコードを記述し、コードが何をしているか

ほとんどの場合、 "debug" -variablesを削除する必要があります。

4
Thomas Junk

最大の問題は明快さです。あなたのコードに無関係なジャンクがたくさんあり、私があなたのコードを維持しているなら、私はすべてが何をしているのかを理解しなければなりません。

その変数は何かに使用されたことがありますか?おそらくそれに対して操作を実行しますが、その値を何かに使用することはありません。変数を単にインクリメントしても、それを一度も読み取らなかった場合(戻り、別の式への入力など)に変数が目的を果たすということにはなりません。

ただし:変数に目的があり、適切に名前が付けられている場合ありないコード全体を損なう。

あなたの更新された質問の例と私が考えたいくつかの他のものを考えると:

  • 別の関数を呼び出して結果を保存し、ログに記録してから返す関数があると、かなり短くて明確になります。

  • 複数の式を含むステートメントを複数のステートメントに分割する(たとえば、長くて複雑な計算を複数の中間変数を含む複数のステートメントに分割する)と、コードmoreを明確にすることができますより冗長になります。一度に処理する情報が少ないと、脳はより簡単に何が起こっているのかを理解できます。

  • 例外を使用しなくても問題ありません。ほとんどの言語では、catchブロックで使用する変数名を指定するなど、キャッチする例外を指定する必要があります。多くの一般的な言語ではこれを回避する方法はなく、プログラマーはそれに慣れています。

どのコード要素に目的があり、どれが私の時間を浪費しているのかを理解するために時間を費やす必要がある場合、私の生産性は低下します。ただし、コードがかなり簡潔で、最初は無関係であるように見えても変数に適切な名前が付けられている場合は、コードを確認して理解するために不必要な時間を浪費するリスクが軽減されます。

無関係な変数、空のブロック、デッドコードを含む不良コードは、開発者がオフィスで悪い評判を得るための1つの方法です。バグ!雪だるまはプログラミング時にひどい!」しかし、コードが目的を果たし、明確な方法で書かれている場合、それは完全に問題ありません。

19
user22815

未使用の変数は、コードのintentを不明確にします。外見にもかかわらず、コードは主にpeopleを読み取るために記述されており、computersではないため、これは悪いことです。

他の人は、値を作成してそれを使用しないと、コードを読んで作業しなければならない他の人々を混乱させることをすでに指摘しています。しかし、私の考えでは、より大きな危険はyourselfになることです。

未使用の変数は意図的なものである場合と、欠陥を指摘する見落としである場合があります。たとえば、名前を間違って入力し、別の場所に値を格納したと思ったときに値を格納した可能性があります。結果のプログラムは問題なく実行できますが、静かに間違った結果を出します。

データフローを分析すると、そのようなエラーや他の多くのエラーを見つけるのに役立ちます。したがって、コードがeverythingデータフローアナライザーが異常であることが実際にはバグであると指摘するような方法でコードを記述することは価値があります。バグを防ぐための自動支援は非常に貴重です。多くの人は「ああ、私は援助を必要としないので、私は不注意になることは決してないだろう」と思っていますが、今のところ私が会ったすべての人はそれが間違っていると思っていました。

5
Kilian Foth

明白な目的を果たさない未使用の変数は、私の見解ではコードのにおいです。せいぜい、それらは注意散漫になる可能性があります-それらはモジュールの一般的なノイズに追加されます。

最悪のケースは、後続のコーダーが何をすべきかを理解し、コードが完全かどうか疑問に思っている時間を費やすことです。自分自身(そして他のすべての人)に好意を払い、取り除きます。

5
Robbie Dee

デバッガーで変数を簡単に確認するという特定の目的のために、関心のある(または関心を持つ可能性のある)変数を意図的に変数に割り当てるコーディングスタイルがあります。これは、次のようなコードに特に役立ちます。

return foo(bar(), baz(wot(12), wombat(&badger)));

関数の名前がいくらか優れていても、次のように記述すると、fooの呼び出しで問題が発生している箇所を簡単に特定できます。

auto awombat = wombat(&badger);
auto awot = wot(12);
auto abaz = baz(awot, abadger);
auto abar = bar();
auto afoo = foo(abar, abaz);
return afoo;

私はこれをデフォルトの構成として実践している人々とはまだ協力していませんが、頑固に拒否するコードを 単一の割り当て形式 で意味をなさないように書き換えると、何が起こっているのかを簡単に理解できますデバッガの下で。その後は常にコードをコンパクトな「きれいな」フォーマットに戻しましたが、それが間違いだったのかと思います。

代わりの方法は、スタックを上下に移動し、あまり遠くに行かないことを期待するか、または(悲惨なことにまれに)リバーシブルデバッガーを使用することです。

それは人気のある戦略ではありませんが、いくつかの不条理なバグを解決するのに役立つので、本質的に悪いと見なされるべきではないと思います。

2

「実際の」コードと同じプロジェクトまたはモジュールにユニットテストコードを含める人にとって、未使用のfieldは、オブジェクトメソッドのように、ユニットテストがすべてをテストしているわけではないことを強く示しています。これにより、開発者が現在使用されていないフィールドまたはメソッドを使用しようとする可能性が高まり、それまで検出されなかったバグに遭遇します。

あまり重要ではないサブルーチンまたはメソッドで未使用の変数は、プログラマがそれを使用するつもりだったが、誤って別の変数を使用していることを示している可能性があります(たとえば、コピー/貼り付け操作後のクリーンアップ後)。

他の人が答えたように、より些細なサブルーチンの未使用の変数はおそらく不要なドロスです。時々、現在コメントアウトされているブレッドクラムステートメントで使用されます。

SomeObject tmp = someMethod();
// printDebugInfoAbout (tmp);

...それがそこで使用され、そこだけで使用されていることは眼に明らかです(つまり、someMethodには重要な副作用があります)が、IDEはそれを知りません。そしてそのような変数を削除することは、その価値があるよりも厄介です。そのような場合、私は一時的に警告サプレッサーを使用します。

1
Paul Brinkley

2つの変数を混在させるコードを記述する場合は簡単です。変数Bを計算しますが、代わりに以前に作成した変数Aを使用します。

したがって、未使用の変数の考えられる理由は、コードに誤りがあることです。コンパイラが警告するのはそのためです。未使用の変数を「行わない」場合、それは完全に無料のプレゼントです。

このような警告が表示された場合は、コードを確認して修正するか、問題のある変数を削除する必要があります。削除しないと、これらの警告に注意を払うのをやめ、完全に無効にすることもできます。しかし、その後、1つのばかげた間違いのために、コードのデバッグを午後に失うことになります。

0
Florian F