This use of curly brackets creates a new block scope.
Each time you write if (...) { ... }
or while (...) { ... }
, the { ... }
part is a new scope. All objects with automatic storage duration created inside (which are usual variables, but not objects allocated dynamically, e.g. via new
) will be destroyed upon reaching the end of the scope. A scope without any if
, while
etc. is useful if you need to constrain the lifetime of something. For example:
{
std::vector<float> some_data = get_the_data();
send_somewhere(some_data);
send_somewhere_else(some_data);
}
Here, after reaching }
, the some_data
object will be destroyed, the memory it allocated will be freed, and you cannot forget to delete it, since it's deletion is guaranteed by the language itself.
Another common example is mutex locking:
// some preparation code
{
std::lock_guard<std::mutex> lock { my_lovely_mutex };
some_shared_resource.modify();
}
// something that does not need the mutex to be locked
Here, the lock_guard
locks the mutex on creation, and unlocks on destruction, even if modify()
throws an exception. Again, you cannot forget to unlock the mutex (and forgetting this is a very dangerous thing to do).
That being said, I don't know the reason to put an assert
into a separate scope - a proper assert
, be it a function or a macro, is usually a self-contained statement and does not need this hackery.
As pointed by Remy Lebeau, probably the assert macro that the author used didn't possess the aforementioned properties, and created variables inside or did something else that pollutes the scope it is called from, thus prohibiting from using it twice. For example, if it were declared (hypothetically) as
#define assert(x) bool b = (x); _internal_assert(b);
Then doing
assert(x);
assert(y);
would trigger a compilation error, because this will expand into
bool b = (x); _internal_assert(b);
bool b = (y); _internal_assert(b);
where the variable b
is declared twice.
Hiding such an assert
in it's own scope fixes this, because variables declared in different scopes do not disturb each other:
{
bool b = (x); _internal_assert(b);
}
// ...
{
bool b = (y); _internal_assert(b);
}