1. ホーム
  2. java

[解決済み] なぜ `++a++` は C++ でコンパイルできないのに `(++a)++` はコンパイルできるのですか?重複

2022-03-14 03:01:20

質問

タイトルに書いてあること C++の場合。 (++a)++ はコンパイルできます。不思議なことに ++(a++) を実行しない。

int main() {
    int a = 0;
    ++a++; // does not compile
    (++a)++; // does compile
    ++(a++); // does not compile
}

しかし、Javaでは、3つともそうなりません。

public class Test {
    public static void main(String[] args) {
        int a = 0;
        ++a++; // does not compile
        (++a)++; // does not compile
        ++(a++); // does not compile
    }
}

C++ではコンパイルできるのに、Javaではできないのは、何か理由があるのでしょうか?

解決方法は?

Java では、postfix と prefix の両方のインクリメント演算が、以下のような結果を返すので、どの例も動作しません。 ではなく 変数 にアクセスすることで確認できます。 JLS のセクションで Postfixインクリメント演算子 ++ を例に挙げて、こう書かれています。

後置インクリメント式の結果は変数ではなく、値です。

のJLSセクションは プリフィックス・インクリメント・オペレーター ++ は同じことを言う。

これは、リテラル値をインクリメントしようとするようなものである ( ライブを見る ):

2++ ;
++3 ;

を実行すると、次のようなエラーが発生します。

required: variable
found:    value

これは、あなたの例で受け取ったのと同じエラーです。

C++では、prefix increment は lvalue を返しますが、postfix increment は prvalue を返し、C++では prefix と postfix increment の両方が lvalue を必要とします。というわけで、1番目と3番目の C++ の例です。

++a++;
++(a++)

は、prvalue に prefix increment を適用しようとしているため、失敗します。一方、2番目のC++の例。

(++a)++;

は、prefix increment が lvalue を返すので大丈夫です。

参考までに C++標準草案 の項では 5.2 Postfixの表現 は言う。

後置++式の値は、そのオペランドの値である [...] オペランドは、変更可能なl値でなければならない。

とする。

その結果は、prvalue

とセクション 5.3 単項式 は言う。

接頭辞 ++ のオペランドが変更される [...] 。 オペランドは、変更可能な l 値でなければならない。

とします。

結果は更新されたオペランドであり、lvalue です。