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;
}
}
Yes, it is good practice to minimise the scope of your variables. It reduces clutter, and reduces the chance of accidentally using the wrong thing at the wrong time.
A scope is a region of the program and broadly speaking there are three places, where variables can be declared: Inside a function or a block which is called local variables, In the definition of function parameters which is called formal parameters. Outside of all functions which is called global variables.
Global variables are useful for values that are relatively constant, or that many functions in the script must access, such as a session id. A local variable, however, has a limited scope: it exists only within the block that it is declared in.
PHP has three different variable scopes: local. global. static.
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).
Yes, you should explicitly scope variables:
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With