12

揮発性パラメーターを持つ関数を呼び出し、そのパラメーターが使用されていない場合でも、コンパイラーはパラメーターを生成する必要がありますか?

void consume( volatile int ) { }

...

consume( some_expr );

GCCはこれを尊重しますが、規格の揮発性の表現がこれを要求するかどうかはわかりません。私の意見では、GCCは正しいことを行っています-これは論理的には揮発性変数への割り当てであるため、省略しないでください(c ++標準の1.9-8による)

注:これの目的は、オプティマイザーがコードの評価を削除しないようにすることです。つまり、強制的some_exprに評価されます。これにより、式を最適化できますが、実際に実行されることが保証されます。

違いがある場合は、両方の興味に対する答えとして、CとC++をタグとして追加しました。しかし、そうなるとは思いません。

答え:最初のものを選んだのは、それが標準の正しい実用的な実現であると信じているからです。ただし、スティーブの哲学的観点は非常に興味深いものであり、実際には標準があいまいであることを意味している可能性があります。

4

2 に答える 2

5

の名前のない引数は名前consumeがないため、読み取ることができません。ただし、初期化されており、その初期化(を使用some_expr)は目に見える副作用です。したがって、コンパイラは初期化を最適化しない可能性があります。

これが実際の評価を必要とするかどうかsome_exprは別の問題です。一般に、これは目に見える副作用ではありませんが、部分式some_exprが含まれている場合は発生する可能性がありvolatileます。

[編集]「名前のない」部分は2か所で発生する可能性があることに注意してください。呼び出し元は一般に、パラメーターに名前が付けられているかどうかを知る方法がありません(使用されることは言うまでもありません)。

void consume( volatile int x);
consume( some_expr );
// other .cpp
void consume( volatile int ) { } // Same function.
于 2012-04-12T13:12:09.587 に答える
1

反対の議論をすることは可能ですが、自動オブジェクトへのアクセスを省略できると思いvolatileます。ただし、それ以外の点ではプログラムに違いがなく、プログラマーがスタックを監視することを禁止している場合(マップされていないページまたは読み取り専用ページを介して)。 、デバッガーなど)、または少なくとも、そうすることで必ずしも期待する効果が得られるとは限らないことを警告します。名前のないパラメータはその説明に適合します。

その理由は、「as-if」ルールが目に見える副作用について話し、揮発性アクセスは目に見える副作用であると言っているためです。しかし、プログラム自体がそれらにまったく依存していない場合、標準は依存しませんオブジェクトは実際には「スタック上」に配置する必要があると言います。この規格では、ハードウェアによって提供される特別なメモリ位置に配置することが許可されています。このメモリ位置は、決して読み取ることはできず、書き込むだけで、ハードウェアに物理的な影響を与えることはありません。それが許可されているので、この効果のない書き込みが実際に先に進むことが「標準で要求されている」と言うのはばかげているようです。誰がどうやって知るのでしょうか?この規格では、書き込みを実行するためにバイナリに命令が必要であるとは義務付けられていません。魔法の読み取り不可能なシークレットオブジェクトが特定の値をとる必要があることが義務付けられています。私がそれがその価値を持っていると主張するならば、あなたは私が間違っていることを証明することはできません:-)

このような揮発性のアクセスが実際に発生することに依存する適合プログラムを作成したり、評価されたかどうかを検出したりすることはできませんsome_expr。計算されたかどうかは、実際にはあなたとデバッガーの間にあります。デバッガーがうまくいかないのを見てきました。

したがって、動作するデバッガーをまったく提供しないことが許可されているのと同じように、実装はそれ自体のデバッガーを壊すことが許可されていると思います。なぜそうしたいのかすぐにはわかりません。実際には、パラメーターをvolatileとしてマークすると、オプティマイザーが見つけられない場所に関数の定義を移動するのとほぼ同じ効果があると思います。値を確実に使用できるように機能します。

于 2012-04-12T13:27:30.993 に答える