Ten dokładny przykład jest omówiony w projekcie normy C99 (te same szczegóły w C11 ), sekcja 6.4 Elementy leksykalne, paragraf 4, który mówi:
Jeśli strumień wejściowy został przeanalizowany na tokeny przetwarzania wstępnego do danego znaku, następny token przetwarzania wstępnego jest najdłuższą sekwencją znaków, która może stanowić token przetwarzania wstępnego. […]
który jest również znany jako reguła maksymalnego chrupania, która jest używana w analizie leksykalnej w celu uniknięcia niejednoznaczności i działa na podstawie jak największej liczby elementów, aby utworzyć prawidłowy token.
akapit zawiera również dwa przykłady, drugi jest dokładnym dopasowaniem do twojego pytania i wygląda następująco:
PRZYKŁAD 2 Fragment programu x +++++ y jest analizowany jako x ++ ++ + y, co narusza ograniczenie operatorów inkrementacji, nawet jeśli analiza x ++ + ++ y może dać prawidłowe wyrażenie.
co mówi nam, że:
a+++++b
zostaną przeanalizowane jako:
a ++ ++ + b
co narusza ograniczenia dotyczące postinkrementacji, ponieważ wynikiem pierwszego postinkrementacji jest rvalue, a po inkrementacji wymaga lwartości. Jest to omówione w sekcji 6.5.2.4
Operatory przyrostowe i dekrementacja, które mówią ( moje podkreślenie ):
Argument operatora zwiększania lub zmniejszania przyrostka powinien mieć kwalifikowaną lub niekwalifikowaną wartość rzeczywistą lub wskaźnikową i być modyfikowalną lwartością.
i
Wynikiem operatora postfix ++ jest wartość operandu.
Książka C ++ Gotchas również omawia ten przypadek w Gotcha #17
Maximal Munch Problems, jest to ten sam problem również w C ++, a także podaje kilka przykładów. Wyjaśnia, że mając do czynienia z następującym zestawem znaków:
->*
analizator leksykalny może zrobić jedną z trzech rzeczy:
- Traktować go jako trzy tokeny:
-
, >
i*
- Traktuj to jako dwa żetony:
->
i*
- Traktuj to jako jeden żeton:
->*
Zasada maksymalnego chrupania pozwala uniknąć tych niejednoznaczności. Autor zwraca uwagę, że to ( w kontekście C ++ ):
rozwiązuje o wiele więcej problemów niż powoduje, ale w dwóch typowych sytuacjach jest to uciążliwe.
Pierwszym przykładem byłyby szablony, których argumenty szablonów są również szablonami ( co zostało rozwiązane w C ++ 11 ), na przykład:
list<vector<string>> lovos;
^^
Który interpretuje zamykające nawiasy kątowe jako operator przesunięcia , więc do ujednoznacznienia wymagana jest spacja:
list< vector<string> > lovos;
^
Drugi przypadek dotyczy domyślnych argumentów wskaźników, na przykład:
void process( const char *= 0 );
^^
zostanie zinterpretowany jako *=
operator przypisania, rozwiązaniem w tym przypadku jest nazwanie parametrów w deklaracji.