Sometimes you run into code that has extra brace brackets, that have nothing to do with scope, only are for readability and avoiding mistakes.
For example:
GetMutexLock( handle ) ;
{
// brace brackets "scope" the lock,
// must close block / remember
// to release the handle.
// similar to C#'s lock construct
}
ReleaseMutexLock( handle ) ;
Other places I have seen it are:
glBegin( GL_TRIANGLES ) ;
{
glVertex3d( .. ) ;
glVertex3d( .. ) ;
glVertex3d( .. ) ;
} // must remember to glEnd!
glEnd() ;
This introduces a compiler error if the mutex isn't freed (assuming you remember both the } and the Release()
call).
In programming, curly braces (the { and } characters) are used in a variety of ways. In C/C++, they are used to signify the start and end of a series of statements. In the following expression, everything between the { and } are executed if the variable mouseDOWNinText is true. See event loop.
These brackets define important constructs in a programming language. For example, in C and languages influenced by C, "{}" denote a code block while "[]" refers to an array subscript. In Perl, the "<>" is referred to as the filehandle operator for reading from and writing to files.
Master C and Embedded C Programming- Learn as you go So we can omit curly braces only there is a single statement under if-else or loop. Here in both of the cases, the Line1 is in the if block but Line2 is not in the if block. So if the condition fails, or it satisfies the Line2 will be executed always.
Different programming languages have various ways to delineate the start and end points of a programming structure, such as a loop, method or conditional statement. For example, Java and C++ are often referred to as curly brace languages because curly braces are used to define the start and end of a code block.
The braces themselves are fine, all they do is limit scope and you won't slow anything down. It can be seen as cleaner. (Always prefer clean code over fast code, if it's cleaner, don't worry about the speed until you profile.)
But with respect to resources it's bad practice because you've put yourself in a position to leak a resource. If anything in the block throws or returns, bang you're dead.
Use Scope-bound Resource Management (SBRM, also known as RAII), which limits a resource to a scope, by using the destructor:
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&);
};
So you get:
{
mutex_lock m(handle);
// brace brackets "scope" the lock,
// AUTOMATICALLY
}
Do this will all resources, it's cleaner and safer. If you are in a position to say "I need to release this resource", you've done it wrong; they should be handled automatically.
Braces affect variable scope. As far as I know that is all they do.
Yes, this can affect how the program is compiled. Destructors will be called at the end of the block instead of waiting until the end of the function.
Often this is what you want to do. For example, your GetMutexLock and ReleaseMutexLock would be much better C++ code written like this:
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
}
Using this more C++ style, the lock is released automatically at the end of the block. It will be released in all circumstances, including exceptions, with the exceptions of setjmp/longjmp or a program crash or abort.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With