Exercise 1-5
Part 1: Is this program valid? If so, what does it do? If not, say why not, and rewrite it to be valid.
#include <iostream> #include <string> int main() { { std::string s = "a string"; { std::string x = s + ", really"; std::cout << s << std::endl; } std::cout << x << std::endl; } return 0; }
Solution
No. The program is not valid and require correction.
Like the previous exercises (1-3 / 1-4), the key to this question is to understanding the term scope. One scope may not “see” what’s inside the other scope(s).
For clarity let me add some comments to the code to visualise these scopes.
// original program with comments added to visualise scope #include <iostream> #include <string> int main() { // scope main starts { // scope main-1 starts std::string s = "a string"; { // scope main-1-1 starts std::string x = s + ", really"; std::cout << s << std::endl; } //scope main-1-1 ends std::cout << x << std::endl; } // scope main-1 ends return 0; } // scope main ends
} // scope main ends
[/code]
Let me start off by stating the following facts (in general)
- All local variables defined at the outer scope level may be seen/used by the inner scopes (at all levels).
- The reverse is not possible however. i.e. All local variables defined at the inner scope level may NOT be seen/used by the outer scopes (at all levels), nor the scopes adjacent to it. (i.e. same level scopes).
- i.e. the permeation of variables go from outer scope, to inner scope. It does not permeate to other scopes at the same level, and/or the inner scopes (at all levels).
To apply these facts to our case:
- scope main-1-1 can see std::string variable s (which is defined in the outer scope main-1), and its own defined std::string variable x.
- scope main-1 can see only its own defined variable std::string s. It cannot see the std::string variable x that lives at the inner scope main-1-1 level. Problem! Fail to perform that std::cout << x << std::endl step because it does not not what x is. from scope main-1 perspective the variable x is not declared.
- scope main-1 has no idea of any variables defined in the inner scopes main-1 nor main-1-1. All it knows is that whenever the implementation hits the return statement, it is done.
To prove the point if we run the program as it is, we expect to see a compilation error
line (19): error: ‘x’ was not declared in this scope
To make the std::string x visible to the scope main-1, simply move the scope main-1-1 up 1 level by removing the curly braces. Like this:
// corrected - likely to work #include <iostream> #include <string> int main() { // scope main starts { // scope main-1 starts std::string s = "a string"; std::string x = s + ", really"; std::cout << s << std::endl; std::cout << x << std::endl; } // scope main-1 ends return 0; } // scope main ends
Running this corrected version program gives us the desirable result, as expected.
a string a string, really Process returned 0 (0x0) execution time : 0.245 s Press any key to continue.