views:

1236

answers:

15

What is the purpose of anonymous { } blocks in C style languages (C, C++, C#)

Example -



void function()
{

  {
    int i = 0;
    i = i + 1;
  }

  {
    int k = 0;
    k = k + 1;
  }

}

Edit - Thanks for all of the excellent answers!

+39  A: 

It limits the scope of variables to the block inside the { }.

17 of 26
+3  A: 

As far as I understand, they are simply for scoping. They allow you to reuse variable names in the parent/sibling scopes, which can be useful from time to time.

EDIT: This question has in fact been answered on another Stack Overflow question. Hope that helps.

Noldorin
+4  A: 

They're very often used for scoping variables, so that variables are local to an arbitrary block defined by the braces. In your example, the variables i and k aren't accessible outside of their enclosing braces so they can't be modified in any sneaky ways, and that those variable names can be re-used elsewhere in your code. Another benefit to using braces to create local scope like this is that in languages with garbage collection, the garbage collector knows that it's safe to clean up out-of-scope variables. That's not available in C/C++, but I believe that it should be in C#.

One simple way to think about it is that the braces define an atomic piece of code, kind of like a namespace, function or method, but without having to actually create a namespace, function or method.

James Thompson
+17  A: 

Brackets designate an area of scope - anything declared within the brackets is invisible outside of them.

Furthermore, in C++ an object allocated on the stack (e.g. without the use of 'new') will be destructed when it goes out of scope.

In some cases it can also be a way to highlight a particular piece of a function that the author feels is worthy of attention for people looking at the source. Whether this is a good use or not is debatable, but I have seen it done.

Andrew Grant
+5  A: 

{ ... } opens up a new scope

In C++, you can use them like this:

void function() {
    // ...
    {
        // lock some mutex.
        mutex_locker lock(m_mutex);
        // ...
    }
    // ...
}

Once control goes out of the block, the mutex locker is destroyed. And in its destructor, it would automatically unlock the mutex that it's connected to. That's very often done, and is called RAII (resource acquisition is initialization) and also SBRM (scope bound resource management). Another common application is to allocate memory, and then in the destructor free that memory again.

Another purpose is to do several similar things:

void function() {
    // set up timer A
    {
        int config = get_config(TIMER_A);
        // ... 
    } 

    // set up timer B
    {
        int config = get_config(TIMER_B);
        // ...
    } 
}

It will keep things separate so one can easily find out the different building blocks. You may use variables having the same name, like the code does above, because they are not visible outside their scope, thus they do not conflict with each other.

Johannes Schaub - litb
+3  A: 

You are doing two things.

  1. You are forcing a scope restriction on the variables in that block.
  2. You are enabling sibling code blocks to use the same variable names.
MichaelD
2 follows implicitly from 1
Nathan Fellman
+2  A: 

It's about the scope, it refers to the visibility of variables and methods in one part of a program to another part of that program, consider this example:

int a=25;
int b=30;
{ //at this point, a=25, b=30
     a*=2; //a=50, b=30
     b /= 2; //a=50,b=15
     int a = b*b; //a=225,b=15  <--- this new a it's
                  //                 declared on the inner scope
}
//a = 50, b = 15
CMS
+11  A: 

They are often useful for RAII purposes, which means that a given resource will be released when the object goes out of scope. For example:

void function()
{
    {
        std::ofstream out( "file.txt" );
        out << "some data\n";
    }
    // You can be sure that "out" is closed here
}
Martin Cote
+3  A: 

As the previous posters mentioned, it limits the use of a variable to the scope in which it is declared.

In garbage collected languages such as C# and Java, it also allows the garbage collector to reclaim memory used by any variables used within the scope (although setting the variables to null would have the same effect).

{
    int[] myArray = new int[1000];
    ... // Do some work
}
// The garbage collector can now reclaim the memory used by myArray
Joe Erickson
Actually, depending on the GC implementation, the JIT should already know that there are no more reads on that variable, and hence it is already eligible for collection.
Marc Gravell
+4  A: 
class ExpensiveObject {
public:
    ExpensiveObject() {
        // acquire a resource
    }
    ~ExpensiveObject() {
        // release the resource
    }
}

int main() {
    // some initial processing
    {
        ExpensiveObject obj;
        // do some expensive stuff with the obj
    } // don't worry, the variable's scope ended, so the destructor was called, and the resources were released
    // some final processing
}
Justice
+1  A: 

If you are limited to ANSI C, then they could be used to declare variables closer to where you use them:

int main() {
    /* Blah blah blah. */
    {
        int i;
        for (i = 0; i < 10; ++i) {
        }
    }
}

Not neccessary with a modern C compiler though.

Bernard
Yes, and sometimes it's merely a visual thing. Also worth noting that anything inside the braces is considered "a statement" for those syntax constructs that "accept only a single statement".
gbarry
+4  A: 

By creating a new scope they can be used to define local variables in a switch statement.

e.g.

switch (i)
{
    case 0 :
        int j = 0;   // error!
        break;

vs.

switch (i)
{
    case 0 :
    {
        int j = 0;   // ok!
    }
    break;
Ferruccio
+6  A: 

Another common use is with OpenGL's glPushMatrix() and glPopMatrix() functions to create logical blocks relating to the matrix stack:

glPushMatrix();
{
    glTranslate(...);
    glPushMatrix();
    {
        glRotate(...);
        // draw some stuff
    }
    glPopMatrix();
    // maybe draw some more stuff
}
glPopMatrix();
Adam Rosenfield
That seems like a good idea for C/C++. In C#, you'd do the same thing via the `using` construct, which would avoid forgetting to pop the matrix at the end, or leaving the stack messed up if an exception is raised.
Drew Noakes
+2  A: 

Scoping of course. (Has that horse been beaten to death yet?)

But if you look at the language definition, you see patterns like:

  • if ( expression )   statement
  • if ( expression )   statement   else   statement
  • switch ( expression )   statement
  • while ( expression )   statement
  • do   statement   while ( expression ) ;

It simplifies the language syntax that compound-statement is just one of several possible statement's.


compound-statement:   { statement-listopt }

statement-list:

  • statement
  • statement-list   statement

statement:

  • labeled-statement
  • expression-statement
  • compound-statement
  • selection-statement
  • iteration-statement
  • jump-statement
  • declaration-statement
  • try-block
Mr.Ree
+1  A: 

I use it for blocks that need temporal variables.

xgoan
do you mean temporary?
Nathan Fellman
Yes, sorry my english level is low :(Thanks!
xgoan