2016-10-20 5 views
4

私はRustとシステムプログラミング全般の初心者です。Rustのconst型をインライン化するのはどういう意味ですか?

定数は、プログラムの全寿命にわたって存在します。具体的には、Rustの定数にはメモリ内の固定アドレスがありません。これは、使用されている各場所に効果的にインライン展開されているためです。同じ定数への参照が、同じ理由で同じメモリアドレスを参照するとは必ずしも保証されません。

私はinline functionsをC++でしか見つけられませんでしたが、インラインconst型はありませんでした。誰かがこれがどのように動作するかの初心者のフレンドリーな説明を提供してください?

また、私は少しno fixed address in memoryと混同しています。つまり、constタイプを使用するたびにスタックの値がこの式のためだけに割り当てられ、式の実行後にが破棄されてになりますか?

答えて

5

私はインライン関数をC++でしか見つけられませんでしたが、インラインconst型は使用しませんでした。

ルストのconstに最も近い数値は、C++でenumです。

この方法の初心者には分かりやすい説明がありますか?

簡単な初心者の説明は、うまくいきます。ちょうどうまくいきます。

また、私はちょっとメモリ内の固定アドレスと混同しています。これは、const型を使うたびにスタックの値がこの式のためだけに割り当てられ、式の実行後に破棄されることを意味しますか?

はい。多分。いいえ

それは錫のことを正確に意味します:保証はありません。これにより、コンパイラは物を最適化する自由度を最大限に引き出します。


申し訳ありませんが、それはすべてうまくいっていますが...実際にはどうなりますか?実際に

は、二つの状況があります。

  • 値が十分に単純です:それもスタックに触れていない、と代わりにアセンブリに直接ハードコードされています。これは、例えば、積分の場合に起こる可能性が最も高い。
  • この値は単純ではありません。読み取り専用メモリに作成され、そこから参照/コピーされます。スタック上の複数のコピーには明らかに異なるアドレスがあります。

単純な意味は何ですか?まあ、それは依存します。各呼び出しサイトに対して、コンパイラは「単純な」かどうかを判断することができます。これはインライン展開に近い場所です。

私たちがconst型を使うたびに、スタック内の値がこの式のためだけに割り当てられ、式の実行後に破棄されますか?

これは破壊されません。 const変数には、Dropを実装する型はありません。その値は使用されなくなったときにを忘れたばかりのです。また、スタック上のメモリが占​​有されていた場合、このメモリは後で時々上書きされます。

+0

なぜC++ enumが最も近いのか説明できますか? –

+2

@PavelStrakhov:C++の 'enum'値は、メモリアドレスを持たない名前付きの値です(' enum {X} 'があれば '&X'でコンパイル時エラーが発生します)、列挙型の値は使用場所ごとにインライン展開されています。それは一度だけ計算されるので(そして、それはもっと洗練されています:スコープなどを尊重します)、 '#define'より少し近いです。 –

+1

コンパイラがコピーを避けるために 'static'に変換することを決めるのと同じように思えますが、本当にそうですか?私はそれを行うためにコンパイラを得ることができないようです。明らかに最適ではない場合でも、式をインライン展開するのと同等のコードを生成します。 – Veedrac

1

const antは通常の変数のようには動作しません。あなたが定義したときには、借用チェックのための独自のスコープも得られません。

fn main() { 
    const N: i32 = 5; 
} 

fn main() { 
    let n: i32 = 5; 
} 

そして、あなたは何をNがより変数より機能のように見えるように展開することを見つける::

はMIRは、次のコードの断片によって生成された比較します

const main::N: i32 = { 
    let mut _0: i32;      // return pointer 

    bb0: { 
     _0 = const 5i32;     // scope 0 at <anon>:2:20: 2:21 
     return;       // scope 0 at <anon>:2:5: 2:22 
    } 
} 

式で使用すると、その値はth eスタックをその式の目的のために使用し、後で忘れてしまいます。

編集:少なくともこれはMIRレベルで発生します。私は低レベルの最適化の専門家ではないので、実際の結果(スタックメモリが実際に使用されたかどうか)は、LLVMまたはASMでチェックする必要があります。ただし、これは通常の変数にも適用できます。

1

const N: i32 = 5は、タイプセーフティを使用してCまたはC++で#define N 5と同じです。

タイプが一致した場合、つまりlet foo = 32 + N;が例のlet foo = 32 + 5;に相当する場合は、テキスト置換のように考えることができます。

+0

'enum'は型の安全性がより高いので、' enum'と '#define'を比較したいと思います。 –

関連する問題