Exercise 1-3
Is the following program valid? if so what does it do? If not, why not?
#include <iostream> #include <string> int main() { { const std::string s = "a string"; std::cout << s << std::endl; } { const std::string s = "another string"; std::cout << s << std::endl; } }
Solution
Yes. The program is valid.
The key to this question is to understanding the term scope. Each pair of curly braces form a scope.
Within the main function (scope), we have two sub-scopes, as defined by the two pairs of curly braces. Visualise these as block 1 and block 2. Block 1 corresponds to line 6 to 9. Block 2 corresponds to line 10 to 13.
Each block constitute its own scope – all local variables and statements within each scope are independent to each other. The const std::string variable s in block 1 is not the same as the const std::string variable s in block 2.
Because of this, even though there is a const std::string variable s in block 1, it is okay to define another constd std::string variable s in block 2 – due to the fact the two variables are in different scope.
It is however not possible to re-define a const std::string variable s within the same block (scope). For instance, the following would not be valid:
{ const std::string s = "a string"; const std::string s = "another string"; // this is not valid. std::cout << s << std::endl; }
For completeness, let’s run that program at the top to confirm it compiles and runs okay.
a string another string Process returned 0 (0x0) execution time : 0.456 s Press any key to continue.
The program runs okay as expected.
Memory Treatment
Another thing to bear in mind is the fact that all local variables within a scope only has a life time within the scope. i.e. once the implementation reaches the closing curly brace, }, (in other words, the end of the scope) the local variables of that scope are destroyed. The memory that was taken up by the local variables are now freed up and returned back to the system.
In this case, as the two blocks of scopes are implemented in a sequential manner, we expect to see the followings memory allocations / de-allocations.
- Line 7: memory allocated for the std::string s variable of scope block 1.
- Line 9: The std::string s variable of scope block 1 is destroyed. Memory is freed up and returned to the system.
- Line 11: memory allocated for the std::string s variable of scope block 2.
- Line 13: The std::string s variable of scope block 2 is destroyed. Memory is freed up and returned to the system.
Awesome explanation.