リテラルス:彼らは記憶を取りますか?

a:

4;
4.0f;
"text";

b:

4.0/5.3;
1.0f*2.3f+3.5f;
"super" + "man";

質問

1)このコードはメモリを占有していますか?

2)bのコードは、aのコードより多くのメモリを占有していますか?

3)誰も内部的に何が起こるかを詳しく説明できますか?

編集: "super" + "man"は悪い例ですが、最初は正しくありません。 (Michael Krelinのおかげで) 第二に、例に文字列を入れるのは悪い考えでした。

2
(a)のコードは、1 int + 1 float + 5 char文字列に必要な領域を占有します。 (b)のコードは、2つの浮動小数点数+ 9の文字列のためのスペースを必要とします。
追加された 著者 Marc B,
@xcrypt:4.0/5.3が何を評価するかによって異なります。それはいつもダブルですか?
追加された 著者 Marc B,
あなたがここに投稿したコードは、文字通り取られた場合、デッドコードであり、最適化する試みさえあるすべてのコンパイラによって削除されます。
追加された 著者 delnan,
@MarcBは、(b)のコードが1ダブル、1フロート、および9文字の配列( "スーパーマン\ 0")のスペースを必要とすることを意味しましたか?
追加された 著者 xcrypt,
@MarcB私はそれを主張するのに十分な経験がない。しかし、私はそれが常に二重に評価されると思う。編集:正確なconstダブル
追加された 著者 xcrypt,

4 答え

コンパイラ、コンピュータのアーキテクチャなどによって異なります。

コンパイラは、結果が常に同じであることが確かである場合、コンパイル時にこれらの式の値を計算する可能性が最も高くなります。式の結果は、結果を計算するのに必要な命令ではなく、出力ファイルに直接配置することができます。しかし、私が知る限り、コンパイラはこれらの種類の最適化を実行する必要はありません。

式がコンパイル時に評価された場合、実行時のパフォーマンスは、ソースコードで直接結果を書いた場合と同じになります。

3
追加された
@xcrypt:それは完全にコンパイラが選択するまでです。 a * 2 を書くと、32ビットレジスタに2を格納してからmultiply命令を呼び出すことができます。または、ビットシフトを使用することもできます。または、 "ax、axを加える"ことができます。コードをコンパイルして、逆アセンブラでバイナリを見て、あなたの特定のケースで何が起こっているかを確認するのが最善です。
追加された 著者 Mark Byers,
ただし、コンパイル時にはすべての用語が一定であり、既知であることを条件とします。
追加された 著者 Will Bickford,
非リテラル整数datamemberにintリテラルを掛けるのはどうでしょうか?この場合、intリテラルは4バイトかかりますか?
追加された 著者 xcrypt,

1)このコードはメモリを占有していますか?

はい

2)bのコードは、<?p>のコードよりも多くのメモリを占有していますか?

コンパイラの結果であるマシンコードによって異なります。おそらくそうです。

3)誰も内部的に何が起こるのか詳しく説明できますか?

コードセグメントデータセグメント

2
追加された
私はダウンワードの気分ではないが、2番目の答えは一般的に間違っている。たぶん普遍的に間違っている。
追加された 著者 Michael Krelin - hacker,

すべての数値式は、Markが上記のようにコンパイル時に評価されます。その後、数値リテラルは直接引数になります。しかし、あなたの質問の他の部分では、文字列リテラルはメモリを占有します。通常、それらはメモリの読み取り専用セクションに格納されます。

2
追加された
  1. これはコードではありませんが、コード内で使用されている場合は、どこかに置きます。
  2. いいえ、コンパイル時に評価されますが、単純に間違っている "super" + "man" 以外は "super" "man" コンパイル時に連結されます。そして "スーパーマン"は "テキスト"よりも大きい。 「4」(整数)は「4.0/5.3」(浮動小数点数)よりも少なくなる可能性があります。
  3. 内部コンパイラは定数式を評価し、それらをどこかに置きます。残りの部分は、あなたが「メモリ」と呼ぶものに依存します。あなたのプログラムのアドレス空間のどこかにあります。
1
追加された
エラー修正のおかげで:)
追加された 著者 xcrypt,