2014-11-19 21 views
6

Cosa dice il titolo. Per C++, compilare (++a)++. Stranamente, però, non lo fa ++(a++):Perché `++ a ++` non viene compilato in C++ ma `(++ a) ++` fa?

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

Ma in Java, non per tutti e tre:

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'è qualche motivo per cui C++ compila questo, ma non in Java?

+0

Cosa C? E in che senso pensi che 'a ++' sia una dichiarazione 'void'? –

+0

@FredLarson Ho usato il compilatore 'C++ 11' su ideone.com, ma penso che sia permesso su qualsiasi compilatore C++. Penso che sia un'istruzione 'void' perché è equivalente (funzionalmente) a:' a = a + 1; 'che non fornisce un valore reale. – Ryan

+0

'" ...un parser che usa solo un token lookahead e nessuna analisi semantica durante l'analisi non sarebbe in grado di dirlo, quando ++ è il token lookahead, se (p) dovrebbe essere considerato un'espressione primaria o lasciato solo per una considerazione successiva come parte di un CastExpression. "' – azurefrog

risposta

11

Nessuno degli esempi lavorano in Java, perché entrambe le operazioni postfix e incremento prefisso restituiscono valori nonvariabili possiamo vedere questo andando alla sezione JLS su Postfix Increment Operator ++ per un esempio e che dice:

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

La sezione JLS per Prefix Increment Operator ++ dice la stessa cosa.

Questo sarebbe come cercare di incrementare un valore letterale (see it live):

2++ ; 
++3 ; 

che dà il seguente errore:

required: variable 
found: value 

Che è lo stesso errore che riceviamo per i vostri esempi .

In C++ l'incremento del prefisso restituisce un valore lvalue, ma l'incremento postfisso restituisce un valore di prvalue e sia l'incremento prefisso e postfisso in C++ richiede un lvalue. Così il vostro primo e terzo esempio C++:

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

fallisce perché si sta tentando di applicare incremento prefisso per un prvalue. Mentre il secondo esempio C++:

(++a)++; 

va bene perché l'incremento di prefisso restituisce un valore.

Per riferimento alla draft C++ standard nella sezione espressioni 5.2Postfix dice:

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

e:

The result is a prvalue

e la sezione 5.3espressioni unarie dice:

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

e: ++ compiler

The result is the updated operand; it is an lvalue

+0

Risposta fantastica, grazie. – Ryan