条件付きに副作用があっても大丈夫ですか?[閉まっている]


10

アメリカの誰もが聞いたことのある大学でCS MSプログラムに参加するための前提条件として、中間データ構造コースを受講しています。クラスで記述された1行のコードが私の目に留まりました。

if (a > 33 | b++ < 54) {...}

これは私の職場でのコードレビューに合格しません。インタビューでこのようなコードを書いた場合、これはあなたに対する重大なストライキとなるでしょう。(副作用のある条件付きであることに加えて、それは明快さを犠牲にして賢いです。)

実際、副作用のある条件式を見たことがなく、グーグルもあまり現れません。授業後も別の学生が留守にしていたので、変だと思ったのは私だけではありません。しかし、教授はこれが許容できるコードであること、そして彼がそのようなものを職場で書くことになることをかなり断固としていた。(彼のFTの仕事は、ご存知の会社のプリンシパルSWEです。)

このコード行が受け入れられる世界は想像できませんが、望ましいことは言うまでもありません。私が間違っている?これでよろしいですか?より一般的なケースはどうですか?副作用のある条件付き?それらは大丈夫ですか?


7
その線は軌道から外されるべきです。十分な量の2倍。
Blrfl

8
nit:単一のパイプ(縦棒)は、論理的な「or」ではなく、ほとんどの言語でビット単位のORです。左辺が真の場合は短絡しません。この条件は右側に副作用があるため、結果に特に大きな違いをもたらします。
ジョナサンユーニス2014

2
このカテゴリに分類されるイディオムがさまざまな言語で使用されていますが、それらは「よく知られている」または「通常の」ものであるため、問題は発生しません。質問の行は慣用的な使用カテゴリに分類されないようなので、回避します。
ジェイディー、2014

2
@JonathanEunice、はい、一部の人々は短絡評価について混乱しました。私のタイプミスではありません。
rianjs 2014

5
明るい面を見てください。これで、インタビューしたくない会社がもう1つあります。
John R. Strohm 2014

回答:


23

ある1私はそのことを考えることができる半条件付き副作用は大丈夫です。while(iter.MoveNext())

とは言っても、これはほとんど「本当に大きな修飾子になることない」というカテゴリーに分類されると思います。私はそれが許容できると思ったいくつかのまれなケースを考えることができますが、一般的にこれは卑劣であり、避けるべきです。

その特定の行が受け入れられるシナリオも考えられませんが、その特定の行が役立つシナリオも考えられないので、そのコンテキストを想像するのは困難です。


これは、クラス中のメソッドの使い捨ての行でした。有用なことを行うことを意図したものではありません。
rianjs 2014

4
同様に、while(v = *p++)ゼロで終了する配列(C文字列など)を介したC / C ++ スタイルのスキャンはかなり一般的で広く受け入れられています。
Phil Miller、

3
私は、フォームのループ条件をwhile(c = input.read() != '\n')かなり慣用的であると見なすことがよくあります。

1
一般的に受け入れられる慣用句がいくつかあるかもしれませんが、明らかに「明快さを犠牲にして賢い」ということは決して絶対にありません。
Julia Hayward 2014

iter.MoveNext()を完全に忘れてしまいました。副作用がある条件付きの完全に合理的なケース。ありがとう!
rianjs 2014

8

私の世界では、メモリからの読み取りは副作用(メモリマップIOなど)と考えられます。

ここで、次のことを考慮してください。

    while( ( *memory_mapped_device_status_register & READY_FLAG) == 0) {
       // Wait
    }

と比較してください:

    status = *memory_mapped_device_status_register;
    while( ( status & READY_FLAG) == 0) {
        // Wait
        status = *memory_mapped_device_status_register;
    }

状態の副作用(読み取り)を回避すると、読みやすさが向上しました。それともコードを複製して混乱を追加しただけですか?

条件に副作用があって(コードが読みにくくなる場合)、条件に副作用がある場合(コードが読みやすくなる場合)も問題ありません。重要な要素は「読みやすさ」です。他はすべて、読みやすさを改善するために見当違いの試みで愚か者が作成したルールです(多くの場合、反対の効果があります)。


3

そのような質問でいつもそうであるように、これは程度の問題です。式内の任意の副作用が常により悪いコードにつながるという明確な証拠がある場合、それらの式を作成することは合法ではありません。言語設計者は、当てにならない人間ideosyncraticかもしれないが、そうではないよという愚かな。if

そうは言っても、内の正当化された副作用の例は何ifですか?たとえば、監査目的でPエンティティのプロパティへのすべてのアクセスとすべてのアクセスを記録することが法的に義務付けられているとしEます。(あなたがウラン濃縮プラントで働いていると想像してください、そしてあなたのコードが何をすることが許され、どのようにそれをすることになっているかに非常に厳しい法的規制があります。)そして、ifそのプロパティをチェックするものはすべて、拡張される監査ログ。

これはかなり明確な分野横断的な懸念事項であり、プログラムの状態に関する推論に(非常に)影響することはありません。また、if(非表示)の行を確認するときに完全に非表示で邪魔にならないように実装できます。アクセサーから離れた場所、またはAOPを使用した場合はさらに便利です)。それは問題ではない副作用のかなり明確なケースだと思います。プロファイリングなどのためにブランチの実行をカウントしたいだけの場合も、同様の状況が想定されます。

これらの緩和する環境がなくなるほど、構成はより奇妙になります。特定のループタイプ(if((c = getc()) == 'x') { quit(); }言語コミュニティでよく知られ、受け入れられている場合など)は、自発的に発明する場合よりもはるかに問題が少ないです。例の行はその標準に達していませんが、私は多くのことを想像できます。私がタイプすることさえないもっとひどいもの、それらはとてもひどいです。


2

本当に臭いコードですが、同等のコードよりもシンプル(そして適切な最適化コンパイラがない場合はおそらくより高速)であるという利点があります。 if (a > 33 | b < 54) {b++; ...} else b++;

もちろん、次のように最適化することもできます(ただし、注意してください。オーバーフローが発生した場合、これは異なる動作になります!): b++; if (a > 33 | b < 53) {...}

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.