32は右辺値ではありません
32はリテラルです
リテラルの返す戻り値(int)が右辺値です
リテラルそのものは単一の式です
またconstで宣言された定数が特定のメモリ領域に属するとは限りません
定数は値のシンボルなのでint &xも単一のシンボルです
定数の扱いは実装依存となります
実際32は右辺値であるにも関わらず左辺値であるかのように振る舞っています
右辺値は左辺値へ代入できませんが、定数なのでメモリの扱いを考慮する必要がありません
では、本来の右辺値を明示的に扱いたい場合はどうするかというと、以下のように宣言します
int &x=(int &)(int &&)32;
左辺値や右辺値はメモリ領域を抽象化します
一方でメモリ外の領域は関知しません
メモリ外の領域とはレジスタなどを指します
値をメモリで扱うにはメモリに値をセットしなければなりません
例えばx64系アーキテクチャでは関数の引数値をいったんレジスタに保存しますが、引数へのアクセスを検知した際にその領域へ改めて値をコピーします
32というリテラルは単一の値である前に一個の命令です
実体が存在するとするならばそれはテキストとしてか、機械語のオペランドとしてです
(int &&)32とすること初めて実体となるデータがメモリに記録されます
一方で
とする時は、既に存在する変数zの領域をxで参照します
これはzのポインタを取っているように見えますが、やはりこれも実装依存です
変数は左辺値を返す手続きとして機能します
int &x=zはintの左辺値をxで受け取る式という意味で、xをポインタとして定義する文脈ではありません
実装次第でxはz自身として振る舞います
xはzのアドレスを取得しているのではなく、領域を格納しています
全てのメモリは、左辺値と右辺値のどちらにも解釈が可能です
例えば変数の領域も右辺値として扱えます
32のような特定のメモリ領域を持たない式は、右辺値として解釈されたメモリにそのままセットされます
右辺値として宣言された変数領域に対するリテラルの適用は、事実上代入と同一です
よって、int &x=(int &)(int &&)32;という式は、右辺値をそのまま左辺値に再解釈して左辺値として宣言された変数領域に代入する手続きとなるので、実質的にint x=32と同義となります
int &x=(int &)(int &&)32;
printf("%d",*&x);