Thread: What does "{}" mean in C++?

  1. #1
    Registered User
    Join Date
    Apr 2007
    Posts
    284

    What does "{}" mean in C++?

    I came across code like this:
    Code:
    ... in middle of some code...
    
    if (some_condition){
      do something;
    
      {//what does it mean?
         string clear_cmd = strfmt( "rm -rf %s/*",data_path.c_str() );                                                                                                              
         system( clear_cmd.c_str() );
      }//what does it mean?
    
      do something else;
    }//end if
    What does the stand-alone "{" and "}" mean? It seems that we don't need the {} pair, and the code can still run correctly.

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    In this context, it introduces a local scope in a block. Take for example:
    Code:
    int main()
    {
    	int num = 0;
    	{
    		int num = 2;
    	}
    }
    If you remove the inner braces, the code certainly will not compile.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    It's a local block. You could think of it as an unnamed namespace or an unnamed function that cannot be called or take any arguments.
    All variables declared within the block will take precedence over more "global" variables (just like if you define a global variable and a local function variable with the same name, the local variable will hide the global one). All variables within the block will be destroyed when the block ends.
    Local blocks can be handy for some things such as switch cases when you aren't allowed to initialize variables.
    Last edited by Elysia; 01-03-2008 at 04:30 AM.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  4. #4
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    >> All variables within the block will be destroyed when the block ends.
    This is probably the most useful reason for local blocks. When using RAII to manage resources you may want objects to go out of scope earlier than the function you use them in so that they will free their resources more quickly. Adding the local block allows you to do this with minimal effects on the rest of the code.

  5. #5
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Quote Originally Posted by Elysia View Post
    predecease
    I think the word you were looking for is precedence

    As Daved says, the primary reason for it is to cause early destruction of RAII items.
    For example say you need to get a lock on the object, read some value, unlock the object and then use the value retreived for something, or perhaps call other functions that would deadlock if this item was still locked. Doing it properly without RAII is just so horrible it usually isn't an option. Not using the extra scope to release the lock early could lead to performance problems, or deadlocks.

    It's hard to get very far into using RAII without becomming quite familiar with this technique.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  6. #6
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by iMalc View Post
    I think the word you were looking for is precedence
    Yes! Curse the FF2 dictionary!
    Thanks for spotting the mistake.

    As Daved says, the primary reason for it is to cause early destruction of RAII items.
    For example say you need to get a lock on the object, read some value, unlock the object and then use the value retreived for something, or perhaps call other functions that would deadlock if this item was still locked. Doing it properly without RAII is just so horrible it usually isn't an option. Not using the extra scope to release the lock early could lead to performance problems, or deadlocks.
    Or you could just make a function to delete the data manually, if you want. I don't know if that's encouraged or not, but that's how I would do thing rather than place blocks around in the code.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  7. #7
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Yeah when you're using an ObjectLock for example you can simply call Unlock on it instead of using the extra scope. However some RAII class types don't have the ability to do such things manually, so you have no choice but to cause the object to be destructed. This is might be because in some cases it would mean having to cope with whether the resource is currently being held or not, and checking the state before doing anything, which adds extra overhead to the class.

    One thing you don't do though, is dynamically allocate the RAII wrapper class just so you can call delete on it at the right time, because then you'd need to wrap that raw pointer in a smart class too, and you're back at the same problem
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  8. #8
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    I might prefer adding the extra scope to calling an Unlock() type method. While the Unlock() call is clearer as to the intent of the code, it also means that the lock object will remain in scope for the rest of the function (or at least the outer scope where it was defined). So after it has been unlocked but is still around, then there is the potential for a person reading the code to miss the unlock and assume the lock is still valid since it is still in scope. You might also accidentally use the object after it has been unlocked which could cause problems.

    Another example of this is an fstream. I'd rarely call close() directly on an fstream because it would be confusing to have it still in scope but not open. Instead I prefer to keep the fstream objects in as small of a scope as possible so that I can let the destructor close the open file automatically.

    >> Or you could just make a function to delete the data manually, if you want. I don't know if
    >> that's encouraged or not, but that's how I would do thing rather than place blocks around
    >> in the code.
    Using RAII to delete the data automatically has the added benefit of deleting the data when an exception is thrown, which is one reason why it is encouraged over making a function to do it manually.

  9. #9
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    I'd rather just write my own RAII classes. But seriously, wrapping RAII classes inside smart pointers isn't always such a bad idea if you need a resource to stay with you until the resource is no longer needed.
    It's back to the local vs. global argument of local or dynamically allocated data again.

    Quote Originally Posted by Daved View Post
    I might prefer adding the extra scope to calling an Unlock() type method. While the Unlock() call is clearer as to the intent of the code, it also means that the lock object will remain in scope for the rest of the function (or at least the outer scope where it was defined). So after it has been unlocked but is still around, then there is the potential for a person reading the code to miss the unlock and assume the lock is still valid since it is still in scope. You might also accidentally use the object after it has been unlocked which could cause problems.
    Then guard it with asserts. Obviously it's a mistake to call a freed object, so just do an assert to catch such mistakes. I'd rather do that than force it to go out of scope.

    Another example of this is an fstream. I'd rarely call close() directly on an fstream because it would be confusing to have it still in scope but not open. Instead I prefer to keep the fstream objects in as small of a scope as possible so that I can let the destructor close the open file automatically.
    Matter of opinion. I'd do the same since the I don't need to reuse the object and don't need to close it prematurely.
    However, this does not necessarily apply to other objects.

    >> Or you could just make a function to delete the data manually, if you want. I don't know if
    >> that's encouraged or not, but that's how I would do thing rather than place blocks around
    >> in the code.
    Using RAII to delete the data automatically has the added benefit of deleting the data when an exception is thrown, which is one reason why it is encouraged over making a function to do it manually.
    Yes, a RAII class should explicitly release data in its destructor, but could also optionally release data when explicitly calling an exposed member function. That's how I like it.
    I can explicitly call it to release date rather than using a local block and resources are automatically freed if an exception is thrown.
    Last edited by Elysia; 01-03-2008 at 01:19 PM.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  10. #10
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Quote Originally Posted by Elysia View Post
    Then guard it with asserts. Obviously it's a mistake to call a freed object, so just do an assert to catch such mistakes. I'd rather do that than force it to go out of scope.
    I think that "the object" might be referring to the class using the ObjectLock, and not the lock itself. Unlock simply unlocks the object for the client. The ObjectLock remains valid, and can be used to re-lock the client object etc.

    I don't think there is a way of asserting that the object is locked either. What's more critical sections allow nested locking so it's possible that depending on where the function was called from, the lock count could differ, so an assert might only sometimes have caught the fault.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  11. #11
    Malum in se abachler's Avatar
    Join Date
    Apr 2007
    Posts
    3,195
    Sorry but only a moron would write a custom class with aserts just to avoid using a local block. Thats like trying to reinvent the wheel, but making it square so it stacks better and out of cheese so it can be multipurpose, and then sealing it in cement so noone can steal it or eat it.

  12. #12
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    No, it's not idiotic and it's not like the analogy you describe.
    It's called creating a solution to a problem.
    And aside from that, I like reinventing the wheel. There are many things that I do not like, including how the STL is built.
    Call it what you want, but don't call it idiotic. Clean and easy code is preferred before complex and difficult code.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Use of "?" ":"
    By MK27 in forum C Programming
    Replies: 6
    Last Post: 12-03-2008, 03:21 AM
  2. What is "..." and "##"
    By meili100 in forum C++ Programming
    Replies: 4
    Last Post: 01-03-2008, 12:08 AM
  3. What does these lines do after ":" mark?
    By asilter in forum C++ Programming
    Replies: 7
    Last Post: 09-27-2007, 07:31 AM
  4. parse error before "{" token
    By getout in forum C Programming
    Replies: 4
    Last Post: 12-31-2006, 01:26 PM
  5. Replies: 3
    Last Post: 11-11-2003, 03:44 AM