Do you use curly braces for additional scoping?

11,176

Solution 1

I do if I am using a resource which I want to free at a specific time eg:

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...
}

Solution 2

I would not use curly braces for that purpose for a couple reasons.

  1. If your particular function is big enough that you need to do various scoping tricks, perhaps break the function into smaller sub-functions.

  2. Introducing braces for scoping to reuse variable names is only going to lead to confusion and trouble in code.

Just my 2 cents, but I have seen a lot of these types of things in other best practice materials.

Solution 3

C++:

Sometimes you need to introduce an extra brace level of scope to reuse variable names when it makes sense to do so:

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

The code above doesn't compile. You need to make it:

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

Solution 4

The most common "non-standard" use of scoping that I use regularly is to utilize a scoped mutex.

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
}

This has many benefits, but the most important is that the lock will always be cleaned up, even if an exception is thrown in the protected code.

Solution 5

The most common use, as others have said, is to ensure that destructors run when you want them to. It's also handy for making platform-specific code a little clearer:

#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
    }

Code built for Windows doesn't see the if, only the braces. This is much clearer than:

#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
Share:
11,176

Related videos on Youtube

blizpasta
Author by

blizpasta

I was a computer science student in it for interest. 'Was' not because I am no longer interested, but because I am no longer a student in the strict sense of belonging to an institution.

Updated on September 28, 2020

Comments

  • blizpasta
    blizpasta over 3 years

    I mean other than using it when required for functions, classes, if, while, switch, try-catch.

    I didn't know that it could be done like this until I saw this SO question.

    In the above link, Eli mentioned that "They use it to fold up their code in logical sections that don't fall into a function, class, loop, etc. that would usually be folded up."

    What other uses are there besides those mentioned?

    Is it a good idea to use curly braces to limit the scope of your variables and expand the scope only if required (working on a "need-to-access" basis)? Or is it actually silly?

    How about using scopes just so that you can use the same variable names in different scopes but in the same bigger scope? Or is it a better practise to reuse the same variable (if you want to use the same variable name) and save on deallocating and allocating (I think some compilers can optimise on this?)? Or is it better to use different variable names altogether?

    • MickyD
      MickyD over 7 years
      Please don't retag your question to include c# 2 years later as it greatly affects the answers and comments on this page
  • Greg Rogers
    Greg Rogers over 15 years
    Yep RAII is the best reason to use "anonymous" scopes instead of creating a new function since the bound scope of the RAII variable is usually very small.
  • Drew Hall
    Drew Hall over 15 years
    Warning: Rant alert! :)
  • Nobody
    Nobody over 13 years
    This is generally my view too - if I need to hide something, i just use #region and #endregion
  • pauloya
    pauloya over 13 years
    You should fix the example to use the same variable "i" on both cases. The code compiles fine if you use "i" and "j".
  • Greg Rogers
    Greg Rogers over 13 years
    @Paulo it shouldn't compile, you should get an error for jumping across the initialization of i. See Section 6.7#3 (incl note 2) of the standard.
  • pauloya
    pauloya over 13 years
    Sorry, I didn't understand what you mean with jumping across the initialization of i, do you have a link to section 6.7#3? It compiled fine on my Snippet Compiler.
  • Greg Rogers
    Greg Rogers over 13 years
    @Paulo csci.csusb.edu/dick/c++std/cd2/stmt.html#stmt.dcl It is possible to transfer into a block, but not in a way that bypasses declarations with initialization. A program that jumps2) from a point where a local variable with automatic storage duration is not in scope to a point where it is in scope is ill-formed unless the variable has POD type (_basic.types_) and is declared without an initializer (_dcl.init_). Also 2) The transfer from the condition of a switch statement to a case label is considered a jump in this respect.
  • pauloya
    pauloya over 13 years
    Oh, you're talking about C++ ! This code works fine on C# :)
  • pauloya
    pauloya over 13 years
    I do use this a lot in C# though when I have repeated variable names in some of the "cases" and I don't think it's appropriate to declare the variable outside the switch.
  • JDB
    JDB over 11 years
    SerialPort implements IDisposable. You should use a using block to ensure the resource is freed.
  • CamW
    CamW almost 10 years
    I agree, functions should be used for scoping, if you're using tricks like anonymous scopes or #region to make your function easier to understand or write then you should definitely split it up into other functions.
  • stringy05
    stringy05 about 8 years
    Great idea! Here's me 8 years later wanting to do exactly the same thing, thanks
  • MickyD
    MickyD over 7 years
    @JDB Question was tagged c+++ at the time and not c# so IDisposable` doesn't apply. Otherwise I totally agree with you
  • Adam Houldsworth
    Adam Houldsworth over 7 years
    @MickyD Fair enough, though in my defense when I came to it it was also tagged C#.
  • MickyD
    MickyD over 7 years
    @AdamHouldsworth No worries. Who moved my cheese? :)