quant
quant

Reputation: 23122

Should I explicitely scope variables?

This is more of a style question because I'm aware that in practice most compilers will probably optimize to give the same effect, but I keep reading that, in general, you should always declare/define variables in the scope that they are used. So in situations where I can't inline the declaration, such as the following snippet, I've thought about enclosing the index variables in scoping brackets (curly brackets, not sure what you call them in this case) in order to explicitely limit the scope of those variables. Is this good practice? If so, can you please explain why?

{
    size_t i = 0; // this variable has no use outside of the range-based for loop
    for (auto const input : input_vector)
    {
        neuron_sequence[i].ForceSignal(input);
        ++i;
    }
}

Upvotes: 6

Views: 812

Answers (4)

Tony Delroy
Tony Delroy

Reputation: 106246

  • Tight scopes are good when you find yourself concerned about the lifetime of the object - typically because of the memory/resources used, or a desire to prevent accidental or facilitate deliberate reuse of the same identifier
    • e.g. doing some repetitive operations - perhaps even using macro substitutions - where a temporary is needed but changing the name serves no particular purpose and is tedious
  • You can't always do this: you'll run into lots of situations where the tightest possible scope that suits one variable overlaps with that of another variable: e.g. trying to "scope" a in { X a = 1; X b(a, 2); ++a; } ++b; destroys b too early
  • In some cases, creating masses of small scopes can considerably bloat the source code, making it harder to visually take in and maintain. There is some mental effort involved to check that the scope introduced doesn't have a controlling if/for/while statement and it's harder at a glance to see the overall function flow. Of course, reducing the number of variables left in scope further down the function can also reduce mental effort - so it's a balancing act.

Overall - it's good to be selective about it, but you'll develop a feeling for when it's warranted. If unsure, it probably doesn't matter.

Upvotes: 0

stardust
stardust

Reputation: 5998

For small data types like integers you really don't need to worry about that because as you said it compilers will optimize the code based on the liveness of a variable and whether it reaches a certain location. In this case it is more of a style issue. And I would recommend not doing it often because code readability and ease of maintenance is also as big of a factor as performance.

However for complex types it can be usefull to limit the lifetime like that. For example for a vector which internally allocates large amounts of memory this can save some space if its scope is limited like that.

Upvotes: 2

RandyGaul
RandyGaul

Reputation: 1915

Of course it's a good practice. It clearly limits where that variable can be used. I do this quite often. Scoping like this is also used to force some objects destructors to run.

For example:

std::vector<int> v;
v.resize( 10 ); // now holds memory for 10 ints

How do you clean up this memory? There's no function to call or any way of manually telling the vector v to clean up its memory. A solution is to force it to go out of scope (assuming I used swap correctly):

std::vector<int> v;
v.resize( 10 ); // now holds memory for 10 ints
{
  std::vector<int> temp;
  temp.swap( v );
} // temp goes out of scope and clears the memory that v used to hold

Another common usage is within switch cases. Often times I need to create a temporary variable in a switch:

switch( val )
{
case constant:
  {
    int x = 10;
    // ... do stuff
  }
}

The last place I can remember off the top of my head is when writing test cases for some sort of code. When unit testing things often times I just want to write my test code as fast as possible without taking much dev-time. So, I place a bunch of related tests within a single function, but wrap up the local variables in separate scopes just to be sure I don't hit any strange bugs (perhaps sharing iterators through tests).

Upvotes: 5

Alok Save
Alok Save

Reputation: 206636

Yes, you should explicitly scope variables:

  1. Scope defines the lifetime of local variables, So scoping the variables appropriately means that the variables are only alive till they serve their desired usage & do not just be alive and hog memory.
  2. In case of same named variables, local vairables hide or shadow the same named global ones. So making the scope explicit improves the readability for the reader.(Atleast i feel so)

Upvotes: 3

Related Questions