Expressions and statements
ES.6
Объявляйте имена в инициализаторах и условиях оператора for для ограничения области видимости
Причина
Читаемость. Ограничение видимости переменной цикла областью видимости цикла. Предотвращение использования переменной цикла в других целях после цикла. Минимизация удержания ресурсов.
Пример
void use()
{
for (string s; cin >> s;)
v.push_back(s);
for (int i = 0; i < 20; ++i) { // хорошо: i локальна для цикла for
// ...
}
if (auto pc = dynamic_cast<Circle*>(ps)) { // хорошо: pc локальна для if
// ... обработка Circle ...
}
else {
// ... обработка ошибки ...
}
}
Пример (не делайте так)
int j; // ПЛОХО: j виден за пределами цикла
for (j = 0; j < 100; ++j) {
// ...
}
// j по-прежнему виден здесь и не нужен
Смотрите также: Don't use a variable for two unrelated purposes
Контроль
- Предупреждайте, когда переменная, изменяемая внутри оператора
for, объявлена вне цикла и не используется за его пределами. - (сложно) Отмечайте переменные цикла, объявленные до цикла и используемые после него в несвязанных целях.
Обсуждение: Ограничение области видимости переменной цикла телом цикла также существенно помогает оптимизаторам кода. Признание того, что индукционная переменная доступна только в теле цикла, открывает такие оптимизации, как вынос инвариантов цикла, снижение стоимости вычислений, перемещение кода, инвариантного относительно цикла, и т.д.
Пример для C++17 и C++20
Примечание: C++17 и C++20 добавляют операторы инициализации в if, switch и range-for. Они требуют поддержки C++17 и C++20.
map<int, string> mymap;
if (auto result = mymap.insert(value); result.second) {
// вставка успешна, и result действителен в этом блоке
use(result.first); // ok
// ...
} // result уничтожается здесь
Контроль для C++17 и C++20 (при использовании компилятора C++17 или C++20)
- Отмечайте переменные выбора/цикла, объявленные до тела и не используемые после тела
- (сложно) Отмечайте переменные выбора/цикла, объявленные до тела и используемые после тела в несвязанных целях.