Используете ли вы фигурные скобки для дополнительной проверки?

Я имею в виду не использовать его, когда это требуется для функций, классов, если, while, switch, try-catch.

Я не знал, что это можно сделать, как пока я не увидел этот вопрос SO.

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

Какие другие виды использования существуют помимо упомянутых?

Хорошо ли использовать фигурные скобки, чтобы ограничить область ваших переменных и расширить область действия только в случае необходимости (работая на основе "необходимости доступа" )? Или это на самом деле глупо?

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

Ответ 1

Если я использую ресурс, который я хочу освободить в определенное время, например:

void myfunction()
{
  {
  // Open serial port
     SerialPort port("COM1", 9600);
     port.doTransfer(data);
  } // Serial port gets closed here.

  for(int i = 0; i < data.size(); i++)
     doProcessData(data[i]);
  etc...
}

Ответ 2

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

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

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

Только мои 2 цента, но я видел много таких вещей в других материалах лучшей практики.

Ответ 3

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

void MyClass::Somefun()
{
    //do some stuff
    {
        // example imlementation that has a mutex passed into a lock object:
        scopedMutex lockObject(m_mutex); 

        // protected code here

    } // mutex is unlocked here
    // more code here
}

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

Ответ 4

С++

Иногда вам нужно ввести дополнительный уровень привязки для повторного использования имен переменных, когда имеет смысл это сделать:

switch (x) {
    case 0:
        int i = 0;
        foo(i);
        break;
    case 1:
        int i = 1;
        bar(i);
        break;
}

Приведенный выше код не компилируется. Вам нужно сделать это:

switch (x) {
    case 0:
        {
            int i = 0;
            foo(i);
        }
        break;
    case 1:
        {
            int i = 1;
            bar(i);
        }
        break;
}

Ответ 5

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

#if defined( UNIX )
    if( some unix-specific condition )
#endif
    {
        // This code should always run on Windows but 
        // only if the above condition holds on unix
    }

Код, созданный для Windows, не видит if, только фигурные скобки. Это намного яснее, чем:

#if defined( UNIX )
    if( some unix-specific condition ) {
#endif
        // This code should always run on Windows but 
        // only if the above condition holds on unix
#if defined( UNIX )
    }
#endif

Ответ 6

Это может быть благом для генераторов кода. Предположим, у вас есть компилятор Embedded SQL (ESQL); он может захотеть преобразовать инструкцию SQL в блок кода, для которого требуются локальные переменные. Используя блок, он может повторно использовать фиксированные имена переменных снова и снова, вместо того, чтобы создавать все переменные с отдельными именами. Конечно, это не слишком сложно, но это сложнее, чем необходимо.

Ответ 7

Как говорили другие, это довольно распространено в С++ из-за всемогущего RAII (инициализация сбора ресурсов) идиома/шаблон.

Для программистов на Java (и, возможно, С#, я не знаю) это будет иностранная концепция, потому что объекты на основе кучи и GC убивают RAII. IMHO, способный помещать объекты в стек, является самым большим единственным преимуществом С++ над Java и делает хорошо написанный код С++ MUCH более чистым, чем хорошо написанный Java-код.

Ответ 8

Я использую его только тогда, когда мне нужно что-то выпускать с помощью RAII, и даже тогда, когда он должен быть выпущен как можно раньше (например, отключение блокировки).

Ответ 9

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

Часто блоки кода слишком коротки, чтобы вырваться на небольшой метод, и часто код в методе структуры (например, startup() или shutdown()), и на самом деле лучше сохранить код вместе одним способом.

Лично я ненавижу обычные плавающие/оборванные фигурные скобки (хотя это потому, что мы являемся строгим отступом в стиле баннера), и я ненавижу маркер комментария:

// yuk!
some code
{
scoped code
}
more code

// also yuk!
some code
/* do xyz */ {
    scoped code
    }
some more code

// this I like
some code
DoXyz: {
    scoped code
    }
some more code

Мы рассмотрели использование "if (true) {", потому что спецификация Java конкретно говорит, что они будут оптимизированы в компиляции (как и весь контент if (false) - это функция отладки), но я ненавидел это в несколько мест я попробовал.

Итак, я думаю, что твоя идея хорошая, совсем не глупо. Я всегда думал, что я единственный, кто хотел это сделать.

Ответ 10

Да, я использую эту технику из-за RAII. Я также использую этот метод в простой C, поскольку он приближает переменные. Конечно, я должен думать о том, чтобы разбить функции еще больше.

Одна вещь, которую я делаю, вероятно, стилистически спорна, ставит открытую фигурную фигуру в строке декларации или помещает на нее комментарий. Я хочу уменьшить количество потерянного вертикального пространства. Это основано на рекомендации руководства по стилю Google С++..

/// c++ code
/// references to boost::test
BOOST_TEST_CASE( curly_brace )
{
  // init
  MyClass instance_to_test( "initial", TestCase::STUFF ); {
    instance_to_test.permutate(42u);
    instance_to_test.rotate_left_face();
    instance_to_test.top_gun();
  }
  { // test check
    const uint8_t kEXP_FAP_BOOST = 240u;
    BOOST_CHECK_EQUAL( instance_to_test.get_fap_boost(), kEXP_FAP_BOOST);
  }
}

Ответ 11

Я согласен с агартцке. Если вы считаете, что вам нужно сегментировать большие блоки логического кода для удобства чтения, вы должны рассмотреть возможность рефакторинга для очистки занятых и загроможденных членов.

Ответ 12

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

Ответ 13

В компании, в которой я работаю, есть политика статического анализа, чтобы поддерживать объявления локальных переменных рядом с началом функции. Много раз использование много строк после первой строки функции, поэтому я не могу сразу увидеть объявление и первую ссылку на экране. То, что я делаю, чтобы "обойти" политику, - это сохранить декларацию рядом с ссылкой, но предоставить дополнительную область, используя фигурные скобки. Однако он увеличивает отступ, и некоторые могут утверждать, что он делает код более уродливым.