Избегайте сложных выражений
Причина
Сложные выражения чреваты ошибками.
Пример
// плохо: присваивание спрятано в подвыражении
while ((c = getc()) != -1)
// плохо: две нелокальные переменные присваиваются в подвыражениях
while ((cin >> c1, cin >> c2), c1 == c2)
// лучше, но, возможно, всё ещё слишком сложно
for (char c1, c2; cin >> c1 >> c2 && c1 == c2;)
// OK: если i и j не являются псевдонимами
int x = ++i + ++j;
// OK: если i != j и i != k
v[i] = v[j] + v[k];
// плохо: несколько присваиваний «спрятаны» в подвыражениях
x = a + (b = f()) + (c = g()) * 7;
// плохо: опирается на часто неправильно понимаемые правила приоритета операторов
x = a & b + c * d && e ^ f == 7;
// плохо: неопределённое поведение
x = x++ + x++ + ++x;
Некоторые из этих выражений безусловно плохи (например, они опираются на неопределённое поведение). Другие просто настолько сложны и/или необычны, что даже хорошие программисты могут неправильно их понять или пропустить проблему в спешке.
Примечание
C++17 ужесточает правила порядка вычислений (слева направо, кроме присваиваний, где порядок справа налево, а порядок вычисления аргументов функции не определён; см. ES.43), но это не меняет того факта, что сложные выражения потенциально запутанны.
Примечание
Программист должен знать и использовать основные правила для выражений.
Пример
x = k * y + z; // OK
auto t1 = k * y; // плохо: излишне многословно
x = t1 + z;
if (0 <= x && x < max) // OK
auto t1 = 0 <= x; // плохо: излишне многословно
auto t2 = x < max;
if (t1 && t2) // ...
Контроль
Сложно. Насколько сложным должно быть выражение, чтобы считаться сложным? Запись вычислений в виде операторов с одной операцией каждый тоже запутывает. Что следует учитывать:
- побочные эффекты: побочные эффекты на несколько нелокальных переменных (для некоторого определения нелокальных) могут быть подозрительны, особенно если побочные эффекты находятся в отдельных подвыражениях
- запись в псевдонимы переменных
- более N операторов (и чему должен равняться N?)
- опора на тонкие правила приоритета
- использование неопределённого поведения (можно ли перехватить всё неопределённое поведение?)
- реализационно-зависимое поведение?
- ???