C++ scope to define a variable?

Viewed 67

Say I have a Class called Tensor and in order to fully construct an instance of the class I need to do a bunch of calculations and define auxiliary variables. In that context, I have seen code from somebody else that used a scope as such:

    Tensor t;
    {
        // lots of calculations to define a, b, c, ..
        t = Tensor(a, b, c, ..)
    }

I think I get the idea: you define the auxiliary variables in a scope because you won't need them again. I'm quite new to C++ and this is the first time encountering this. Typically I see the scope when defining a Class or a function. I've googled and found an example here, under the heading "Point of declaration".

Is this good practice? When should I use it? Should I avoid it? Does it have anything to do with garbage collection?

2 Answers

Is this good practice? When should I use it? Should I avoid it?

Reduce scope of variable is generally good, but it is generally better to initialize variable instead of set them later (so you can have const for example).

Creating a function or invoking a lamdba would be even better than the scope:

/* const */ Tensor t1 = make_tensor(/*..*/);
/* const */ Tensor t2 = []()
    {
        // lots of calculations to define a, b, c, ..
        return Tensor(a, b, c, ..);
    }(); // extra parents to call directly the lambda
// a, b, c are no longer accessible, and so cannot be misused.

So unless you need to expose a, b and/or c, or the scope is already short to not really have to worry about it (especially if there are const), I would reduce scope by above techniques.

Does it have anything to do with garbage collection?

Nothing at all.

Is this good practice?

It is not bad practice.

When should I use it?

A common use case is with RAII-helper types. Consider the example presented on cppreference for scoped_lock (comments added by me):

void assign_lunch_partner(Employee &e1, Employee &e2)
{
    static std::mutex io_mutex;
    {
        std::lock_guard<std::mutex> lk(io_mutex);
        std::cout << e1.id << " and " << e2.id << " are waiting for locks" << std::endl;
    }   // <--
 
    {
    // [...]

The lock lk automatically releases the mutex when it goes out of scope. This couple of lines is probably not worth the effort to put them inside a dedicated function, so the author just opened a scope such that the lock only holds the mutex till } // <--.

Should I avoid it?

This whole idea of not introducing a function, but just a scope is no longer maintanable when the size of the code is more than just a couple of lines. Though this is purely opinion-based and a matter of style.

Does it have anything to do with garbage collection?

No. It has nothing to do with garbage collection. As illustrated above, it has something to do with RAII.

Related