Рассмотрите следующий фрагмент:
int a,b;
a = 1;
b = 2;
c = a++++b; // does not work!! Compilation error.
c = a++*+b; // works !!
Помогите мне понять это поведение.
c = a++++b;
обрабатывается как:
c = ((a++)++)b;
, что неверно, поскольку вы пытаетесь увеличить значение, отличное от lvalue.
и
c = a++*+b;
рассматриваются как:
c = (a++)*(+b);
Причина такого поведения: Лексический анализатор языка C жадный .
В случае 1: после токена «a» (идентификатор) лексический анализатор видит +, за которым следует еще один +, поэтому он использует оба (как оператор приращения) как часть одного и того же токена. Это не делает третью + часть того же токена, что и +++, недействительным токеном. Точно так же он группирует следующие два + в токен ++, что делает его таким же, как:
c = ((a++)++)b;
, что неверно, поскольку ++ не вернет lvalue, поэтому вы не можете применить к нему ++. Что-то похожее на 5 ++;
Но в случае 2: первая пара ++ будет сгруппирована вместе (как оператор приращения). Затем только * будет токеном, так как вы не можете комбинировать его с +, поскольку * + не является допустимым токеном. Наконец, + будет токеном (как унарным +), эффективно превращающим ваше утверждение в следующее:
c = (a++)*(+b);
Вы можете переопределить это жадное поведение лексера, используя круглые скобки или пробелы следующим образом:
c = a++ + +b;
c = a++ * +b;
Это эффективно из-за максимального правила Munk « » в C.
c = a++++b;
анализируется как C = A ++ ++ B;
, что является синтаксической ошибкой.
c = a++*+b;
анализируется как C = A ++ * + B;
, который в порядке.
От проекта C99, раздел 6.4P4 (упор для ухода):
Если входной поток был проанализирован в предварительно обработке токенов до данного символа, следующий предварительный токен представляет собой длинную последовательность символов, которые могли представляют собой предварительно обработанный токен .
Оператор Приоритет . ++ имеет высокий приоритет, чем двоичный +.
precedance of ++ равно precedance of +. Поэтому мы используем left to right.
Та же причина, по которой мы получаем ошибку в C ++ для:
vector<vector<int>>;
>>
будет рассматриваться как один оператор.