0

I'm trying to solve some problems in c++ but I have never seen this expression before. Since I don't know what the expression is called, I can't google it.

int main() {
   int something=1;

   {
     assert(something);
   }

   // What is the purpose of these braces?
   // and what is it called?
   {
     assert(something != NULL);
   }

   return;
}
Dr.Knowitall
  • 10,080
  • 23
  • 82
  • 133
  • 6
    They are creating additional local scope blocks. Presumably `assert()` is a precompiler macro that internally declares some variables that should go out of scope when `assert()` exits, but doesn't itself declare its own scope blocks – Remy Lebeau Jun 21 '18 at 22:16
  • 3
    Why is this question too broad? Its a very specific question with a narrow context. – Dr.Knowitall Jun 21 '18 at 22:34
  • Whatever, I got my answer. I don't care about my SO reputation. Thanks for the help guys. – Dr.Knowitall Jun 21 '18 at 22:36
  • @Dr.Knowitall I'd suppose that closing was suggested because questions on basic language constructs are usually commented with "get a good C++ book" and closed. What is "basic" and what isn't is not entirely clear to me, though. – lisyarus Jun 21 '18 at 22:41
  • Duplicate of [this question](https://stackoverflow.com/questions/9704083/unnecessary-curly-braces-in-c)? – BlameTheBits Jun 21 '18 at 22:51

2 Answers2

7

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);
}
lisyarus
  • 15,025
  • 3
  • 43
  • 68
  • 1
    "*probably the assert macro that the author used didn't possess the aforementioned properties*" - And the fix for such a "broken" macro would be something like this: `#define assert(x) do { bool b = (x); _internal_assert(b); } while(false);` – Remy Lebeau Jun 21 '18 at 22:45
  • @RemyLebeau True! This is the `assert` I'm most familiar with. – lisyarus Jun 21 '18 at 22:47
0
  • { Denotes the start of a block
  • } Denotes the end of a block

Blocks effect scope. In the case you've presented, they serve no purpose other than to meet the style of the author.

Christopher Pisz
  • 3,757
  • 4
  • 29
  • 65