mi chiedo perché in C# seguente va bene:Perché x ++ - + - ++ x legale ma x +++ - +++ x non lo è?
int y = x++-+-++x;
Ma
int y = x+++-+++x;
non lo è? Perché c'è un pregiudizio contro il +?
mi chiedo perché in C# seguente va bene:Perché x ++ - + - ++ x legale ma x +++ - +++ x non lo è?
int y = x++-+-++x;
Ma
int y = x+++-+++x;
non lo è? Perché c'è un pregiudizio contro il +?
Le altre due risposte sono corrette; Vorrei aggiungere a loro che questo illustra alcuni principi di base di analisi lessicale:
Questi principi implicano che +++x
saranno lexed come ++ + x
e non + ++ x
.
Il parser quindi analizzare ++ + x
come ++(+x)
, e (+x)
non è una variabile , è un valore, quindi non può essere incrementato.
Consulta anche: http://blogs.msdn.com/b/ericlippert/archive/2010/10/11/10070831.aspx
+1, anche se ciò renderebbe strano che Mono può compilare lo stesso codice. O la specifica è un po '"aperta" su quel lato, o uno dei compilatori non è all'altezza delle specifiche. –
@JoachimIsaksson: Mono ha un piccolo bug; Sospetto che sia nell'analizzatore semantico, non nell'analizzatore lessicale. Cioè, è ** non ** il caso che Mono è lexing '+++ x' come' + ++ x'. Piuttosto, ho il sospetto che sia il lexing corretto come '++ + x', quindi l'analizzatore semantico sta trattando' + x' come 'x', ma dimenticando che' + x' è un valore, non una variabile, e quindi non idoneo come operando dell'incremento. –
@JoachimIsaksson: Infatti. Il compilatore Microsoft C# conteneva un certo numero di errori di questo tipo in C# 2.0; Ho rimosso molti di loro in C# 3.0. Alcuni li abbiamo trattenuti perché erano innocui e prendere il cambiamento di rottura sarebbe stato di disturbo. –
Sto usando VS 2012. Questo è un po 'interessante.
Il primo può essere analizzato in:
int y = (x++) - (+(-(++x)));
senza cambiare il risultato finale. Quindi puoi capire perché sarebbe valido.
Il secondo, tuttavia, ha un problema con lo +++x
perché (sto indovinando) vede i due ++ e prova ad applicare quell'operatore unario al valore r, che è un altro + (e non un valore R valido). È possibile raggruppare in vari modi per farlo funzionare, però:
int y = (x++)+(-(+(++x)));
è valido.
Sono sicuro che Jon Skeet o Eric Lippert o qualcuno si presenteranno e indicheranno la parte rilevante delle specifiche C#. Non sono nemmeno sicuro da dove cominciare. Ma seguendo solo l'analisi generale dei token da sinistra a destra, puoi vedere dove si soffocerebbe sul secondo.
FYI l'intera grammatica è alla fine della specifica in un'appendice. –
Non si vede nulla se non "uno di" sulla grammatica dell'operatore, se preferire "+" o "++" in qualsiasi momento sembra vago. –
@JoachimIsaksson: La sezione 2.3 della specifica dice * "Quando diverse produzioni grammaticali lessicali corrispondono a una sequenza di caratteri in un file sorgente, l'elaborazione lessicale costituisce sempre l'elemento lessicale più lungo possibile." * –
Il compilatore sta cercando una variabile o una proprietà dopo il secondo ++
in int y = x+++-+++x
e non può determinare quello senza spazio o parentesi.
Si può fare qualcosa di simile:
int y = x+++-+(++x);
o
int y = x++ + -+ ++x;
se si voleva.
Il motivo per cui il primo esempio che hai elencato ha funzionato è perché il compilatore può determinare che +-
da ++x
; mentre nel secondo esempio non è possibile determinare dove separare il +++
e naturalmente si aspetta una variabile dopo aver letto il primo ++
; quindi, in breve, il compilatore tenta di utilizzare +x
come variabile, che non è valido.
Entrambi sono probabilmente validi utilizzando un altro compilatore. Dipende dalla semantica.
Meglio domanda è: perché si vuole utilizzare questo? – Sayse
Dipende dal compilatore (.Net 4.5 su reclami VS 2012) –
Abbiamo bisogno di informazioni specifiche su quale compilatore stai usando, su quale cosa hai come target, ecc. – tnw