Это плохая практика для создания блоков кода?

12

В C ++ плохая практика - создавать блоки кода внутри какой-либо функции, например:

    bool f()
    {
       {
           double test = 0;

           test = // some other variable outside this function, for example.

           if (test == // some value)
             return true;
       }

       {
           double test = 0;

           test = // some variable outside this function, different from the last one.

           if (test == // some value)
             return true;
       }

       return false;

    }

Смысл этого состоит в том, чтобы использовать одно и то же имя переменной «test» несколько раз для одного и того же типа процедуры. В моем проекте у меня несколько переменных, и я выполняю несколько тестов. Я не хочу продолжать создавать новые переменные с разными именами для каждого из тестов, учитывая, насколько они похожи.

Это плохая практика - вставлять блоки кода, чтобы переменные выходили из области видимости после каждого теста, а затем я мог снова использовать их имена? Или я должен искать другое решение? Следует отметить, что я решил использовать один и тот же набор переменных для всех моих тестов (и просто установить их все в 0 после завершения каждого теста), но у меня сложилось впечатление, что это может быть плохой практикой.

Инерционное невежество
источник
19
Если бы я открывал этот код, я бы сказал, что вы должны разделить каждый из этих тестов на отдельные методы ... Как следствие, вам не нужно будет использовать блоки кода для их отдельной области.
Maybe_Factor
1
@ Maybe_Factor - согласен. Преимущество отдельных методов заключается в том, что вы можете называть каждый блок, обеспечивая более читаемый код.
Mouviciel
@mouviciel Не только более читаемый код, но и более читаемые отчеты о тестировании!
Maybe_Factor
@ Maybe_Factor Я не согласен. Перемещение вещей в отдельные функции отрицательно сказывается на их функциональности. Хранить всю логику для функции в одном месте - это хорошо.
Майлз Рут
1
@MilesRout Это не одна логическая функция, это множественные модульные тесты для функции, объединенной в одну тестовую функцию. Блоки кода против функций в обычном коде - еще одно обсуждение.
Возможно_Factor

Ответы:

22

Блоки вполне разумны, если вы используете их для выделения ресурсов. Файлы, сетевые подключения, выделения памяти, транзакции базы данных, что угодно. В этих случаях блок фактически является частью логической структуры кода: вы порождаете ресурс, он существует в течение некоторого периода времени, а затем он уходит в назначенное время.

Но если все, что вы делаете, это определение имени , то я бы сказал, что это плохая практика. Вообще говоря, конечно; могут применяться особые обстоятельства.

Например, если эта функция была сгенерирована какой-либо системой генерации кода, инфраструктурой тестирования или тому подобным, то блоки для определения имен являются разумной вещью. Но вы будете говорить о коде, написанном для машины, а не человека.

Если человек пишет код, в котором ему нужно повторно использовать имена в одной и той же функции, я бы сказал, что эти блоки, вероятно, должны быть отдельными функциями. Особенно, если эти имена используются с разными типами и / или значением в этих блоках.

Николь Болас
источник
10

Это не плохая практика для создания таких блоков. Это как работают области видимости.

Обычно это делается при использовании RAII (Resource Acquisition is Initialization), и вы хотите контролировать, когда будут вызываться деструкторы.

Если он будет длинным, я подумаю о том, чтобы переместить этот код в его собственную функцию.

По моему мнению, просто использовать его для переработки имен переменных не очень хорошая идея. Но я вижу, что это было полезно в случаях с нехваткой памяти

Роберт Анджейюк
источник
Повторное использование имен локальных переменных не влияет на использование памяти.
Кевин Клайн
1
Не думаете ли вы, что умный оптимизатор мог бы использовать 1 ячейку памяти для 2 переменных?
Роберт
3
Да. Но он также может сделать это, если они находятся в одной области видимости, если у них нет деструкторов.
Себастьян Редл