Questo esempio esatto è trattato nella bozza dello standard C99 ( stessi dettagli in C11 ) sezione 6.4 Elementi lessicali paragrafo 4 che in dice:
Se il flusso di input è stato analizzato in token di pre-elaborazione fino a un dato carattere, il token di pre-elaborazione successivo è la sequenza di caratteri più lunga che potrebbe costituire un token di pre-elaborazione. [...]
che è anche conosciuta come la regola del munch massimale che viene utilizzata nell'analisi lessicale per evitare ambiguità e funziona prendendo il maggior numero di elementi possibile per formare un segno valido.
il paragrafo ha anche due esempi il secondo è una corrispondenza esatta per la tua domanda ed è il seguente:
ESEMPIO 2 Il frammento di programma x +++++ y viene analizzato come x ++ ++ + y, che viola un vincolo sugli operatori di incremento, anche se l'analisi x ++ + ++ y potrebbe produrre un'espressione corretta.
che ci dice che:
a+++++b
sarà analizzato come:
a ++ ++ + b
che viola i vincoli sull'incremento di post poiché il risultato del primo incremento di post è un rvalue e l'incremento di post richiede un lvalue. Questo è trattato nella sezione 6.5.2.4
Operatori di incremento e decremento di Postfix che dice ( enfasi mia ):
L'operando dell'operatore di incremento o decremento postfisso deve avere un tipo reale o puntatore qualificato o non qualificato e deve essere un valore modificabile.
e
Il risultato dell'operatore postfisso ++ è il valore dell'operando.
Il libro C ++ Gotchas copre anche questo caso in Gotcha #17
Maximal Munch Problems , è lo stesso problema anche in C ++ e fornisce anche alcuni esempi. Spiega che quando si ha a che fare con il seguente set di caratteri:
->*
l'analizzatore lessicale può fare una di tre cose:
- Trattarlo come tre gettoni:
-
, >
e*
- Trattalo come due gettoni:
->
e*
- Trattalo come un token:
->*
La regola del munch massimo consente di evitare queste ambiguità. L'autore sottolinea che ( nel contesto C ++ ):
risolve molti più problemi di quanti ne provoca, ma in due situazioni comuni è un fastidio.
Il primo esempio sarebbero i modelli i cui argomenti del modello sono anche modelli ( che è stato risolto in C ++ 11 ), ad esempio:
list<vector<string>> lovos; // error!
^^
Che interpreta le parentesi angolari di chiusura come l' operatore di spostamento , quindi è necessario uno spazio per disambiguare:
list< vector<string> > lovos;
^
Il secondo caso riguarda argomenti predefiniti per i puntatori, ad esempio:
void process( const char *= 0 ); // error!
^^
verrebbe interpretato come *=
operatore di assegnazione, la soluzione in questo caso è nominare i parametri nella dichiarazione.