2014-11-19 17 views
6

Co mówi tytuł. Dla C++, (++a)++ jest kompilowany. O dziwo jednak, ++(a++) nie:Dlaczego `++ a ++` nie kompiluje się w C++, ale `(++ a) ++` ma?

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

Ale w Javie, że nie dla wszystkich trzech:

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

Czy istnieje jakikolwiek powód, dlaczego C++ kompiluje tego, ale nie w Java?

+0

Co kompilator C++? I w jakim sensie uważasz, że 'a ++' jest stwierdzeniem 'void'? –

+0

@FredLarson Użyłem kompilatora 'C++ 11' na ideone.com, ale myślę, że jest on dozwolony w każdym kompilatorze C++. Myślę, że jest to polecenie "void", ponieważ jest równoważne (funkcjonalnie) do: 'a = a + 1;' które nie daje rzeczywistej wartości. – Ryan

+0

'" ...parser używający tylko jednego znaku wyprzedzającego i żadnej analizy semantycznej podczas analizy nie byłby w stanie powiedzieć, kiedy ++ jest znacznikiem wyprzedzającym, czy (p) powinno być uważane za wyrażenie podstawowe lub pozostawione w spokoju do późniejszego rozpatrzenia jako część CastExpression. "' – azurefrog

Odpowiedz

11

Żaden z przykładów pracy w Javie, ponieważ obie operacje Postfix oraz prefiks przyrost powrócić wartości nie zmienne możemy zobaczyć, przechodząc do sekcji JLS na Postfix Increment Operator ++ dla przykładu i jest napisane:

The result of the postfix increment expression is not a variable, but a value.

Sekcja JLS dla Prefix Increment Operator ++ mówi to samo.

Byłoby to jak próbuje zwiększyć wartość literalną (see it live):

2++ ; 
++3 ; 

co daje następujący błąd:

required: variable 
found: value 

który jest taki sam błąd, że otrzymane dla przykładów .

W przyrostku przedrostka C++ zwraca wartość l, ale przyrostek przyrostowy zwraca prwartość, a przyrost przyrostka przedrostka i przyrostka w C++ wymaga wartości l. Tak więc Twój pierwszy i trzeci przykład C++:

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

nie powiedzie się, ponieważ próbujesz zastosować przyrost prefiksu do wartości prinn. Podczas gdy drugi przykład C++:

(++a)++; 

jest w porządku, ponieważ przyrostek prefiksu zwraca wartość l.

Dla odsyłającym draft C++ standard w sekcji wyrażenia 5.2Postfix mówi:

The value of a postfix ++ expression is the value of its operand [...] The operand shall be a modifiable lvalue

oraz:

The result is a prvalue

i sekcja 5.3wyrażenia Jednoargumentowe mówi:

The operand of prefix ++ is modified [...] The operand shall be a modifiable lvalue

i:

The result is the updated operand; it is an lvalue

+0

Fantastyczna odpowiedź, dzięki. – Ryan

Powiązane problemy