10

http://thbecker.net/articles/rvalue_references/section_01.htmlを読んでいるときに、次のようなスニピエストを取得しました。

// lvalues:
//
int i = 42;
i = 43; // ok, i is an lvalue
int& foo();
foo() = 42; // ok, foo() is an lvalue
int* p1 = &foo(); // ok, foo() is an lvalue

// rvalues:
//
int foobar();
int j = 0;
j = foobar(); // ok, foobar() is an rvalue
int* p2 = &foobar(); // error, cannot take the address of an rvalue
j = 42; // ok, 42 is an rvalue

なぜ int* p2 = &foobar(); int* p1 = &foo(); はエラー ステートメントです。エラーではありません。最初のものは右辺値ですが、左辺値はどれくらい後ですか?

前もって感謝します

4

2 に答える 2

13

以下に示す C のサンプル コードがあるとします。これはコンパイルされますか? 左辺値と右辺値の概念はこの問題でどのように機能しますか?

#define X 8
int main(void)
{
    ++X; // will this line compile?
        return 0;

}

上記のコードと、問われている問題を本当に理解するには、左辺値と右辺値の概念を少し説明する必要があります。先に進む前に、ここで示した左辺値と右辺値の定義は厳密ではないことに注意してください。C 標準自体でさえ定義がかなり曖昧です。

右辺値と左辺値の違い

オブジェクトは、調べることができるメモリの領域ですが、必ずしも変更する必要はありません。左辺値は、そのようなオブジェクトを参照する式です。左辺値という用語は、元々、式の左辺 (したがって「l」) に現れるオブジェクトを指していました。const 修飾された型も左辺値と見なされるため、その定義は適用されなくなりましたが、変更できないため、割り当てステートメントの左側に表示されることはありません。したがって、「変更可能な左辺値」という用語は、変更可能な左辺値を指すために作成されたものであり、const 修飾された型はこのカテゴリに分類されません。

右辺値は、値を持つが値を割り当てることができない任意の式です。右辺値は、左辺値ではない任意の式であるとも言えます。右辺値の例は、'8' や '3.14' などのリテラル定数です。したがって、明らかに上記のコードの値 '8' は右辺値です。

左辺値と右辺値の理解を使用して質問に答える

それでは、問題を解決してみましょう。厳密に言えば、前置 (または後置) インクリメント演算子のオペランドは、変更可能な左辺値でなければなりません。では、上記のコードの前置インクリメント演算子のオペランドは何ですか?

X はマクロなので、プリプロセッサの実行後、上記のステートメントは「++8」に展開されます。これは、「8」がプレフィックスインクリメント演算子のオペランドであることを意味します。また、8 は右辺値であるため、「++」の引数として使用できません。これは、上記のコードがコンパイルされないことを意味します。

于 2013-06-28T05:42:32.017 に答える