2016-09-11 7 views
5

私はまだC++を学んでいます。私は評価がどのように実行されているかをむしろ段階的に理解しようとしています。したがって、この単純な例を使用すると、式文:C++の式評価: "Under the Hood"はどうなりますか?

int x = 8 * 5 - 5;

これは私がと信じているのはです。

  1. オペランドx、8、5、および5が「評価されました」。おそらく、各値を保持するために一時オブジェクトが作成されます(これについてはあまりよく分かりません)。

  2. 8 * 5は、一時的に格納される40と評価されます。

  3. 40(一時的) - 5は35(別の一時的な)と評価されます。

  4. 35がxにコピーされます。

  5. すべての一時オブジェクトは、作成された逆の順序で破棄されます(値は破棄されます)。

私は少なくとも右に近いですか?

+4

非常に高いレベルの見通しから、はい。実際には、操作はCPUレジスタで実行されます。実際の現実では、コンパイル時に式全体が評価されるため、コンパイル結果はすべて「x = 35」になります。 –

+0

質問を見つけて、それを重複としてマークしましょう... –

+0

@SamVarshavchikありがとうございます。 Hm。すべてのオペランドがリテラルではなくオブジェクトに名前を付けるとどうなりますか?コンパイル時よりもむしろ、一時期をオンザフライで作成するのだろうか? –

答えて

0

"ありがとうございました。すべてのオペランドがリテラルではなくオブジェクトに名前を付けられたとしたらどうなりますか?コンパイル時ではなく、その場で仮引数を作成するのでしょうか?

サムが言いましたように、あなたは高いレベルで適切なトラックにいます。 最初の例では、(名前付きオブジェクトではないため)一時レジスタを保存するためにCPUレジスタを使用します。名前付きオブジェクトの場合は、コンパイラで設定された最適化フラグと、最適化された 'コードが生成されます。あなたは本当に何が起こるかを見るために逆アセンブリを見ることができます。たとえば、あなたがしなければ

a = 5; 
b = 2; 
c = a * b; 

試してみて、最適なコードを生成し、この場合にはそこにコンパイル時に知られている2つの定数であり、そしてあなたは2の乗算を行い以来だろうコンパイラ、それは次のようになりますショートカットを取ることができます。乗算は、より安価なビット演算に置き換えられることがあります(2を掛けると1を左にシフトするのと同じです)。

名前付き変数は、スタックまたはヒープのいずれかに、名前付きオブジェクトのアドレスを使用してそれらを渡し、関数を実行します。 (十分小さい場合は、レジスタに収まるようになり、それ以外の場合はメモリを使用して最初にキャッシュに入り、RAMにブリードアウトします)

「抽象構文ツリー」のためのgoogleは、どのように読み込み可能なC++コードがマシンコードに変換されるかのアイデア。

これは、constの正確さ、エイリアシング、およびポインタと参照の関係を学ぶことが重要であるため、最適なコードを生成する最適な機会をコンパイラに与えるためです。 (ユーザーがそれから得る利点を除いて)