文字列リテラルは配列です。つまり、本質的にサイズが予測できないオブジェクトです (つまり、ユーザー定義のサイズが大きい可能性があります)。一般に、そのようなリテラルをメモリ内のオブジェクトとして、つまり として表現する以外に表現する方法は他にありませんlvalues
。C99 では、これは複合リテラルにも適用されlvalues
ます。
文字列リテラルが言語レベルにあるという事実を人為的に隠そうlvalues
とすると、かなりの数の完全に不必要な問題が発生します。ポインターを使用して文字列リテラルを指す機能と配列としてアクセスする機能は非常に依存しているためです。言語レベルで見える左辺値性について。
一方、スカラー型のリテラルは、コンパイル時のサイズが固定されています。同時に、そのようなリテラルは、特定のハードウェア アーキテクチャのマシン コマンドに直接埋め込まれている可能性が非常に高くなります。たとえば、 のようなものを記述するとi = i * 5 + 2
、リテラル値5
and2
は、生成されたマシン コードの明示的な (または暗黙的な) 部分になります。それらは存在せず、データ ストレージ内のスタンドアロンの場所として存在する必要もありません。値5
を格納2
したり、データ メモリに格納したりするだけでは意味がありません。
また、多くの (ほとんどまたはすべてではないにしても) ハードウェア アーキテクチャでは、浮動小数点リテラルが実際には "非表示" として実装されていることも注目に値しますlvalues
(たとえ言語がそれらをそのように公開していなくても)。x86 のようなプラットフォームでは、浮動小数点グループからのマシン コマンドは埋め込み即値オペランドをサポートしません。つまり、ほぼすべての浮動小数点リテラルは、コンパイラによってデータ メモリに格納 (およびデータ メモリから読み取られる) される必要があります。たとえば、次のようなものを書くと、次のようなi = i * 5.5 + 2.1
ものに翻訳されます
const double unnamed_double_5_5 = 5.5;
const double unnamed_double_2_1 = 2.1;
i = i * unnamed_double_5_5 + unnamed_double_2_1;
つまり、社内でfloating-point literals
「非公式」になってしまうことが多いのです。lvalues
ただし、言語仕様がこの実装の詳細を公開しようとしなかったことは完全に理にかなっています。言語レベルではarithmetic literals
、より理にかなっていrvalues
ます。