Дополнительные скобки в коде C ++

Недавно я написал HTML-дезинфицирующее средство в Java. Он основан на смешанном подходе регулярных выражений и Java-коде. Лично я ненавижу регулярные выражения и его глупость (читаемость, ремонтопригодность и т. Д.), Но если вы уменьшите объем своих приложений, это может соответствовать вашим потребностям. Во всяком случае, мой дезинфицирующее средство использует белый список для тегов HTML и черный список для некоторых атрибутов стиля.

Для вашего удобства я создал игровое поле, чтобы вы могли проверить, соответствует ли код вашим требованиям: игровая площадка и код Java . Ваши отзывы будут оценены.

Существует небольшая статья, описывающая эту работу в моем блоге: http://roberto.open-lab.com

13
задан noɥʇʎԀʎzɐɹƆ 26 July 2017 в 23:00
поделиться

8 ответов

Сами фигурные скобки в порядке, все, что они делают, это ограничивают область действия, и вы ничего не замедлите. Его можно рассматривать как более чистый. (Всегда предпочитайте чистый код быстрому коду, если он чище, не беспокойтесь о скорости, пока не профилируете.)


Но в отношении ресурсов это плохая практика, потому что вы поставили себя в положение утечки ресурса. Если что-то в блоке бросает или возвращается, удар вы мертвы.

Используйте управление ресурсами с привязкой к области (SBRM, также известное как RAII), которое ограничивает ресурс областью, используя деструктор:

class mutex_lock
{
public:
    mutex_lock(HANDLE pHandle) :
    mHandle(pHandle)
    {
        //acquire resource
        GetMutexLock(mHandle);
    }

    ~mutex_lock()
    {
        // release resource, bound to scope
        ReleaseMutexLock(mHandle);
    }

private:
    // resource
    HANDLE mHandle;

    // noncopyable
    mutex_lock(const mutex_lock&);
    mutex_lock& operator=(const mutex_lock&);
};

Итак, вы получите:

{
  mutex_lock m(handle);
  // brace brackets "scope" the lock,
  // AUTOMATICALLY
}

Сделайте это, чтобы все ресурсы, это чище и безопаснее. Если вы в состоянии сказать: «Мне нужно освободить этот ресурс», вы сделали это неправильно; они должны обрабатываться автоматически.

32
ответ дан 1 December 2019 в 17:21
поделиться

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

Я не знаю, что вы имеете в виду, говоря «это приводит к ошибке компилятора, если мьютекс не освобожден». Это просто неправда. Такое использование {...} не может и не приведет к каким-либо ошибкам компилятора.

Является ли это хорошей практикой - дело личных предпочтений. Выглядит нормально. В качестве альтернативы вы можете использовать комментарии и / или отступы для обозначения логической группировки операторов в коде без каких-либо дополнительных {...} .

Существуют различные методы, основанные на области видимости, некоторые из которых были проиллюстрированы другими ответами здесь, но то, что у вас есть в вашем OP, даже отдаленно не похоже на это. Еще раз, то, что у вас есть в OP (как показано), является чисто исходной привычкой форматирования с лишними {...} , которые не влияют на сгенерированный код.

3
ответ дан 1 December 2019 в 17:21
поделиться

Все, что улучшает читаемость, IMHO, является хорошей практикой. Если добавление фигурных скобок улучшает читаемость, дерзайте!

Добавление дополнительных скобок не изменит способ компиляции кода. Это не замедлит работу программы.

1
ответ дан 1 December 2019 в 17:21
поделиться

Это намного полезнее (IMHO) в C ++ с деструкторами объектов; ваши примеры находятся на C.

Представьте, что вы создали класс MutexLock:

class MutexLock {
private:
    HANDLE handle;
public:
    MutexLock() : handle(0) {
        GetMutexLock(handle);
    }

    ~MutexLock() {
        ReleaseMutexLock(handle);
    }
}

Тогда вы могли бы ограничить эту блокировку только кодом, который в ней нуждался, предоставив новую область видимости с фигурными скобками:

{
    MutexLock mtx;  // Allocated on the stack in this new scope

    // Use shared resource
}
// When this scope exits the destructor on mtx is called and the stack is popped
1
ответ дан 1 December 2019 в 17:21
поделиться

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

2
ответ дан 1 December 2019 в 17:21
поделиться

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

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

Часто это то, что вы хотите сделать. Например, ваши GetMutexLock и ReleaseMutexLock были бы намного лучше кода C++, написанного следующим образом:

struct MutexLocker {
  Handle handle;
  MutexLocker(handle) : handle(handle) { GetMutexLock(handle); }
  ~MutexLocker() { ReleaseMutexLock(handle); }    
};
...
{
  MutexLocker lock(handle);
  // brace brackets "scope" the lock,
  // must close block / remember
  // to release the handle.
  // similar to C#'s lock construct
}

Используя этот стиль C++, блокировка освобождается автоматически в конце блока. Он будет выпущен при любых обстоятельствах, включая исключения, за исключением setjmp/longjmp или сбоя или прерывания программы.

17
ответ дан 1 December 2019 в 17:21
поделиться

Это неплохая практика. Это не делает ничего медленнее; это просто способ структурирования кода.

Заставить компилятор выполнять проверку и принудительное выполнение ошибок за вас — это всегда хорошо!

3
ответ дан 1 December 2019 в 17:21
поделиться

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

Лично я бы назвал это плохой практикой; Способ избежать ошибок, которые вы можете здесь совершить, заключается в использовании ограниченного управления ресурсами (иногда называемого RAII), а не в использовании типографских напоминаний, подверженных ошибкам. Я бы написал код как что-то вроде

{
    mutex::scoped_lock lock(mutex);
    // brace brackets *really* scope the lock
}   // scoped_lock destructor releases the lock

{
    gl_group gl(GL_TRIANGLES); // calls glBegin()
    gl.Vertex3d( .. );
    gl.Vertex3d( .. );
    gl.Vertex3d( .. );
} // gl_group destructor calls glEnd()
2
ответ дан 1 December 2019 в 17:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: