Reputation:
Although the example below compiles fine except for the last line with the error, I'd like to know the ins and outs of this 'scoping' within a scope? Also the terminology of this, if any.
Consider these brackets:
void func()
{
int i = 0;
{ // nice comment to describe this scope
while( i < 10 )
++i;
}
{ // nice comment to describe this scope
int j= 0;
while( j< 10 )
++j;
}
i = 0; // OK
// j = 0; // error C2065
}
consider this:
error C2065: 'j' : undeclared identifier
edit: Accepted answer is from bitmask, although I think everyone should place it in the context of anio's answer. Especially, quote: "perhaps you should break your function into 2 functions"
Upvotes: 3
Views: 378
Reputation: 477030
Yes, definitely - it's a great habit to always keep your variables as local as possible! Some examples:
for (std::string line; std::getline(std::cin, line); ) // does not
{ // leak "line"
// process "line" // into ambient
} // scope
int result;
{ // putting this in a separate scope
int a = foo(); // allows us to copy/paste the entire
a += 3; // block without worrying about
int b = bar(a); // repeated declarators
result *= (a + 2*b);
}
{ // ...and we never really needed
int a = foo(); // a and b outside of this anyway!
a += 3;
int b = bar(a);
result *= (a + 2*b);
}
Sometimes a scope is necessary for synchronisation, and you want to keep the critical section as short as possible:
int global_counter = 0;
std::mutex gctr_mx;
void I_run_many_times_concurrently()
{
int a = expensive_computation();
{
std::lock_guard<std::mutex> _(gctr_mx);
global_counter += a;
}
expensive_cleanup();
}
Upvotes: 4
Reputation: 52107
The explicit scoping is usually not done for commenting purposes, but I don't see any harm in doing it if you feel it makes your code more readable.
Typical usage is for avoiding name clashes and controlling when the destructors are called.
Upvotes: 3
Reputation: 34628
Do. By all means!
Keeping data as local as possible and as const as possible has two main advantages:
Additionally, this can be useful for documentation to summarise the job a particular part of a function does.
I've heard this being referred to as explicit or dummy scoping.
Upvotes: 7
Reputation: 76245
A pair of curly braces defines a scope. Names declared or defined within a scope are not visible outside that scope, which is why j
is not defined at the end. If a name in a scope is the same as a name defined earlier and outside that scope, it hides the outer name.
Upvotes: 2
Reputation: 9161
I personally don't find much value in adding additional scoping within a function. If you are relying on it to separate parts of your function, perhaps you should break your function into 2 functions. Smaller functions are better than larger ones. You should strive to have small easily understood functions.
The one legitimate use of scopes within a function is for limiting the duration of a lock:
int doX()
{
// Do some work
{
//Acquire lock
} // Lock automatically released because of RAII
}
The inner scope effectively limits the code over which the lock is held. I believe this is common practice.
Upvotes: 6