Делая сегодня обзор кода для коллеги, я увидел странную вещь. Он окружил свой новый код такими фигурными скобками:
Constructor::Constructor()
{
existing code
{
New code: do some new fancy stuff here
}
existing code
}
Каков результат, если таковые имеются, из этого? Что может быть причиной для этого? Откуда эта привычка?
Редактировать:
Исходя из входных данных и некоторых вопросов ниже, я чувствую, что мне нужно добавить некоторые вопросы, хотя я уже отметил ответ.
Среда встроенных устройств. Существует много устаревшего кода C, обернутого в одежду C ++. Есть много разработчиков C ++, ставших C ++.
В этой части кода нет критических разделов. Я видел это только в этой части кода. Здесь не делается никаких больших выделений памяти, только установлены некоторые флаги и некоторые изменения.
Код, заключенный в фигурные скобки, выглядит примерно так:
{
bool isInit;
(void)isStillInInitMode(&isInit);
if (isInit) {
return isInit;
}
}
(Не обращайте внимания на код, просто придерживайтесь фигурных скобок ...;)) После фигурных скобок есть еще немного перемешивания, проверки состояния и базовой сигнализации.
Я поговорил с этим парнем, и его мотивация заключалась в том, чтобы ограничить область действия переменных, назвать конфликты и некоторые другие, которые я не мог поднять.
Из моего POV это кажется довольно странным, и я не думаю, что фигурные скобки должны быть в нашем коде. Во всех ответах я видел несколько хороших примеров того, почему можно заключать код в фигурные скобки, но не следует ли вместо этого разделить код на методы?
источник
Ответы:
Иногда это приятно, так как дает вам новую область видимости, где вы можете более «аккуратно» объявить новые (автоматические) переменные.
В
C++
это может быть не так важно , так как вы можете ввести новые переменные в любом месте, но , возможно, привычка изC
, где вы не можете сделать это до C99. :)Так как
C++
имеет деструкторы, также может быть удобно, чтобы ресурсы (файлы, мьютексы и т. Д.) Автоматически высвобождались при выходе из области видимости, что может сделать вещи чище. Это означает, что вы можете удерживать некоторый общий ресурс в течение более короткого промежутка времени, чем если бы вы взяли его в начале метода.источник
Одной из возможных целей является управление переменной области . А поскольку переменные с автоматическим хранением уничтожаются при выходе из области видимости, это также позволяет деструктору вызываться раньше, чем в противном случае.
источник
for
заявлений, чтобы создать недолговечноеint i;
в C89. Конечно, вы не предлагаете, чтобы каждыйfor
был в отдельной функции?Дополнительные фигурные скобки используются для определения области действия переменной, объявленной внутри фигурных скобок. Это сделано для того, чтобы деструктор вызывался, когда переменная выходит из области видимости. В деструкторе вы можете освободить мьютекс (или любой другой ресурс), чтобы другие могли его получить.
В моем производственном коде я написал что-то вроде этого:
Как вы можете видеть, таким образом вы можете использовать
scoped_lock
функцию и в то же время определять ее область действия с помощью дополнительных фигурных скобок. Это гарантирует, что даже если код вне дополнительных фигурных скобок может быть выполнен несколькими потоками одновременно, код внутри фигурных скобок будет выполняться ровно одним потоком за раз.источник
scoped_lock
который будет уничтожен на исключениях. Я обычно предпочитаю также ввести новую область видимости для блокировки, но в некоторых случаяхunlock
это очень полезно. Например, чтобы объявить новую локальную переменную в критическом разделе, а затем использовать ее позже. (Я знаю, что опоздал, но только для полноты ...)Как уже отмечали другие, новый блок вводит новую область видимости, позволяя писать немного кода со своими собственными переменными, которые не разрушают пространство имен окружающего кода и не используют ресурсы дольше, чем это необходимо.
Однако есть еще одна веская причина для этого.
Это просто для выделения блока кода, который достигает определенной (под) цели. Редко когда один оператор достигает вычислительного эффекта, который я хочу; обычно это занимает несколько Размещение их в блоке (с комментарием) позволяет мне сказать читателю (часто самому себе позже):
например
Вы можете утверждать, что я должен написать функцию, чтобы сделать все это. Если я делаю это только один раз, написание функции просто добавляет дополнительный синтаксис и параметры; кажется, мало смысла. Просто представьте, что это анонимная функция без параметров.
Если вам повезет, у вашего редактора будет функция сгиба / раскрытия, которая даже позволит вам скрыть блок.
Я все время это делаю. Мне очень приятно знать границы кода, который мне нужно проверить, и еще лучше знать, что если этот кусок не тот, который я хочу, мне не нужно смотреть ни на одну из строк.
источник
Одной из причин может быть то, что время жизни любых переменных, объявленных внутри нового блока фигурных скобок, ограничено этим блоком. Еще одна причина, которая приходит на ум, - возможность использовать свертывание кода в любимом редакторе.
источник
Это то же самое, что и блок
if
(илиwhile
т. Д.), Только без негоif
. Другими словами, вы вводите область действия, не вводя управляющую структуру.Эта «явная область видимости» обычно полезна в следующих случаях:
using
.Пример 1:
Если
my_variable
случается, что это особенно удачное имя для двух разных переменных, которые используются изолированно друг от друга, то явная область видимости позволяет вам не придумывать новое имя просто для того, чтобы избежать конфликта имен.Это также позволяет избежать
my_variable
случайного использования не по назначению.Пример 2:
Практические ситуации, когда это полезно, редки и могут указывать на то, что код созрел для рефакторинга, но механизм есть, если он вам действительно нужен.
Пример 3:
Это может быть важно для RAII в случаях, когда потребность в освобождении ресурсов не «естественно» попадает на границы функций или структур управления.
источник
Это действительно полезно при использовании замков с областью действия в сочетании с критическими секциями в многопоточном программировании. Ваша блокировка с ограничением по объему, инициализированная в фигурных скобках (обычно это первая команда), выйдет из области видимости в конце конца блока, и другие потоки смогут снова работать.
источник
Все остальные уже правильно рассмотрели возможности определения объема, RAII и т. Д., Но поскольку вы упоминаете встроенную среду, есть еще одна потенциальная причина:
Возможно, разработчик не доверяет распределению регистров этого компилятора или хочет явно контролировать размер фрейма стека, одновременно ограничивая количество автоматических переменных в области видимости.
Здесь
isInit
, скорее всего, будет в стеке:Если вы уберете фигурные скобки, пространство для
isInit
может быть зарезервировано в кадре стека даже после его потенциального повторного использования: если имеется много автоматических переменных с аналогично локализованной областью действия, а размер стека ограничен, это может стать проблемой.Точно так же, если ваша переменная назначена регистру, выход из области видимости должен дать четкую подсказку, что регистр теперь доступен для повторного использования. Вы должны посмотреть на ассемблер, сгенерированный с и без фигурных скобок, чтобы выяснить, действительно ли это имеет значение (и профилировать его - или наблюдать за переполнением стека - чтобы увидеть, действительно ли это различие имеет значение).
источник
Я думаю, что другие уже рассмотрели область видимости, поэтому я упомяну, что ненужные скобки могут также служить цели в процессе разработки. Например, предположим, что вы работаете над оптимизацией существующей функции. Переключение оптимизации или отслеживание ошибки в определенной последовательности операторов является простым для программиста - см. Комментарий перед фигурными скобками:
Эта практика полезна в определенных контекстах, таких как отладка, встроенные устройства или персональный код.
источник
Я согласен с "руах". Если вы хотите получить хорошее объяснение различных уровней области видимости в C, посмотрите этот пост:
Различные уровни области применения в приложении C
В общем, использование «Область видимости блока» полезно, если вы хотите просто использовать временную переменную, которую не нужно отслеживать в течение всего времени существования вызова функции. Кроме того, некоторые люди используют его, чтобы вы могли использовать одно и то же имя переменной в нескольких местах для удобства, хотя это, как правило, не очень хорошая идея. например:
В этом конкретном примере я определил returnValue дважды, но, поскольку он находится только в области видимости блока, а не в области действия функции (т. Е. Область действия функции будет, например, объявлять returnValue сразу после int main (void)), я не получить любые ошибки компилятора, так как каждый блок не обращает внимания на объявленный временный экземпляр returnValue.
Я не могу сказать, что это хорошая идея в целом (то есть: вам, вероятно, не следует повторно использовать имена переменных из блока в блок), но в целом это экономит время и позволяет избежать необходимости управлять значение returnValue для всей функции.
Наконец, обратите внимание на область применения переменных, используемых в моем примере кода:
источник
Итак, зачем использовать «ненужные» фигурные скобки?
#pragma
или определение «разделов», которые можно визуализировать)PS Это не плохой код; это на 100% действительно. Так что это скорее вопрос (необычного) вкуса.
источник
После просмотра кода в редактировании я могу сказать, что ненужные скобки, вероятно (в исходном представлении кодеров), на 100% ясны, что произойдет во время if / then, даже если сейчас это только одна строка, это может быть несколько строк позже, и скобки гарантируют, что вы не ошибетесь.
если вышеупомянутое было оригинальным, и удаление "лишних" приводит к:
тогда более поздняя модификация может выглядеть так:
и это, конечно, вызовет проблему, поскольку теперь isInit всегда будет возвращаться независимо от if / then.
источник
Объекты автоматически уничтожаются, когда они выходят из области видимости ...
источник
Другим примером использования являются классы, связанные с пользовательским интерфейсом, особенно Qt.
Например, у вас есть сложный пользовательский интерфейс и множество виджетов, каждый из которых имеет свой собственный интервал, макет и т. Д. Вместо того, чтобы называть их,
space1, space2, spaceBetween, layout1, ...
вы можете уберечь себя от неописательных имен для переменных, которые существуют только в двух-трех строках. код.Ну, некоторые могут сказать, что вы должны разделить его на методы, но создание 40 одноразовых методов выглядит не очень хорошо, поэтому я решил просто добавить фигурные скобки и комментарии перед ними, чтобы это выглядело как логический блок. Пример:
Не могу сказать, что это лучшая практика, но она хороша для устаревшего кода.
Эти проблемы возникли, когда многие люди добавили свои собственные компоненты в пользовательский интерфейс, а некоторые методы стали действительно массовыми, но нецелесообразно создавать 40 одноразовых методов внутри класса, которые уже испортились.
источник