-1

foo() が副作用を生成し、整数を返す次の C コードがあるとします。

if(bar) {
    foo();
    return 0;
}

さて、おそらく読者の費用負担で、コードをコンパクトにするのが本当に好きで、これを次のように変更するとします。

if (bar)
    return foo() && 0;

これら 2 つのコードが同じ動作を生成することを確認できますか? または、コンパイラの最適化などの可能性があるために foo() の呼び出しが実行されず、目的の副作用が発生しないリスクがありますか?

: これはどちらのコードが優れているかという問題ではなく、2 つの部分が実際にすべてのケースで同じ動作をするかどうかという問題です。大多数 (そして私) は、前者のコードを使用することに同意できると思います。

4

3 に答える 3

3

はい、その2つは同じです。 foo()常に呼び出されます (true であると仮定しbarます)。

于 2013-11-10T22:45:58.597 に答える
1

指定した 2 つの形式は同等です。C11 標準 (ドラフト n1570) には、次のように記載されています。

6.5.13 論理 AND 演算子
...
セマンティクス

3 && 演算子は、両方のオペランドが 0 と等しくない場合、1 を返します。
  それ以外の場合は 0 になります。結果の型は int です。
4 ビットごとのバイナリ & 演算子とは異なり、&& 演算子は左から右への
  評価; 2 番目のオペランドが評価される場合、間にシーケンス ポイントがあります。
  1 番目と 2 番目のオペランドの評価。最初のオペランドが比較する場合
  0 の場合、2 番目のオペランドは評価されません。

同様の言語は、これまでのすべての C 標準に登場しました。

次の理由から、ここではコンマ演算子 ( return foo(), 0;)を使用することをお勧めします。

  • それはより短いです (演算子の場合は 1 文字に対して 2 文字であり、カンマを使用するときに左のスペース文字を削除することで、合計で 2 文字少なくなります)。
  • 非スカラー型 (構造体など) を返すことができ、0 または 1 よりも広い範囲の整数を返すことができるため、柔軟性が向上します。
  • 「の戻り値を破棄し、代わりにfoo()何か他のものを返す」という意図をよりよく伝え0ます。

への呼び出しを削除するコンパイラにたまたま遭遇した場合、コンパイラはそれが目に見える副作用のない関数であるfoo()ことを証明したか、深刻なバグがある可能性が高く、報告する必要があります。foo()

于 2013-11-11T03:32:37.067 に答える