[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

4.8 拡張左辺値

複文式、3項演算式、それにキャストは、そのオペランドが左辺値であれば、 左辺値として許される。つまり、これらのアドレスを取ったり、値を格納出来る。

C++ の標準は、複文式と3項演算子式を左辺値として使うこと、 それから参照型へのキャストを許しているので、C++ のコードでは この拡張を使う意味はあまりない。

例えば、複文式は題入可能である。列の最後の式が左辺値となる。 以下の二つの式は等価である。

 
(a, b) += 5
a, (b += 5)

同様に、複文式のアドレスを取ることができる。 以下の二つの式は等価である。

 
&(a, b)
a, &b

条件式は、その型が void でなくて、真の分岐と偽の分岐がどちらも有効な 左辺値なら、やはり有効な左辺となる。 例えば、以下の二つの式は等価である。

 
(a ? b : c) = 5
(a ? b = 5 : (c = 5))

キャストも、そのオペランドが左辺値であれば、有効な左辺値である。 左辺がキャストである単純な代入の場合、まず右辺がキャストで指定される タイプに変換され、次にキャストなしの左辺式の型に変換される。 それが格納された後、その値はキャストで指定された型に戻されて、 代入自体の値となる。 つまり、a の型が char * という場合、以下の二つの式は 等価である。

 
(int)a = 5
(int)(a = (char *)(int)5)

+=’ のように算術演算と組み合わされた代入演算をキャストに 適用すると、キャストの結果の型を使って算術演算を行ない、 次に前述の場合と同じように続行される。つまり、以下の二つの式は 等価になる。

 
(int)a += 5
(int)(a = (char *)(int) ((int)a + 5))

左辺値のキャストのアドレスを取ることはできない。 そのアドレスを使うと一貫性がなくなるからである。 &(int)f という書き方が許されるとしよう。 f の型は float 型とする。 そうすると、以下の文は、整数のビットパターンを浮動小数点数が属する 場所に格納しようとすることになる。

 
*&(int)f = 1;

これは、(int)f = 1 が行なうことと全く違う。 (int)f = 1 は、1 を浮動小数点に変換し、それを格納する。 この一貫性のなさを発生させるよりも、キャストに ‘&’ を 使うのを禁止したほうが良いだろうと我々は考えている。

f のアドレスを int * 型のポインタとして本当に必要なら、 単に (int *)&f と書けば良い。


This document was generated using texi2html 1.78.