Cet exemple exact est couvert dans le projet de norme C99 ( mêmes détails dans C11 ) section 6.4 Éléments lexicaux paragraphe 4 qui dit:
Si le flux d'entrée a été analysé en jetons de prétraitement jusqu'à un caractère donné, le jeton de prétraitement suivant est la plus longue séquence de caractères pouvant constituer un jeton de prétraitement. [...]
qui est également connue sous le nom de règle de munch maximal qui est utilisée dans l'analyse lexicale pour éviter les ambiguïtés et fonctionne en prenant autant d'éléments que possible pour former un jeton valide.
le paragraphe contient également deux exemples, le second correspond exactement à votre question et se présente comme suit:
EXEMPLE 2 Le fragment de programme x +++++ y est analysé comme x ++ ++ + y, ce qui viole une contrainte sur les opérateurs d'incrémentation, même si l'analyse x ++ + ++ y peut donner une expression correcte.
ce qui nous dit que:
a+++++b
sera analysé comme suit:
a ++ ++ + b
ce qui viole les contraintes de post-incrémentation puisque le résultat du premier post-incrément est une rvalue et que post-increment nécessite une lvalue. Ceci est couvert dans la section6.5.2.4
Opérateurs d'incrémentation et de décrémentation de Postfix qui dit (c'est moi qui souligne ):
L'opérande de l'opérateur d'incrémentation ou de décrémentation postfixe doit avoir un type réel ou pointeur qualifié ou non et doit être une valeur l modifiable.
et
Le résultat de l'opérateur postfix ++ est la valeur de l'opérande.
Le livre C ++ Gotchas couvre également ce cas dans Gotcha #17
Maximal Munch Problems c'est le même problème dans C ++ et il donne également quelques exemples. Il explique que lorsqu'il s'agit de l'ensemble de caractères suivant:
->*
l'analyseur lexical peut faire l'une des trois choses suivantes:
- Traiter comme trois jetons:
-
,>
et*
- Traitez-le comme deux jetons:
->
et*
- Traitez-le comme un jeton:
->*
Le munch maximal règle de permet d'éviter ces ambiguïtés. L'auteur précise qu'il ( dans le contexte C ++ ):
résout beaucoup plus de problèmes qu'il n'en cause, mais dans deux situations courantes, c'est une gêne.
Le premier exemple serait des modèles dont les arguments de modèle sont également des modèles ( ce qui a été résolu en C ++ 11 ), par exemple:
list<vector<string>> lovos; // error!
^^
Ce qui interprète les crochets angulaires de fermeture comme l' opérateur de décalage , et donc un espace est nécessaire pour lever l'ambiguïté:
list< vector<string> > lovos;
^
Le deuxième cas concerne les arguments par défaut pour les pointeurs, par exemple:
void process( const char *= 0 ); // error!
^^
serait interprété comme un *=
opérateur d'affectation, la solution dans ce cas est de nommer les paramètres dans la déclaration.