[C++] Funky magic with scopes & consts

I found something pretty baffling in c++ language while diddling around with the K&M exercise 1-4. It feels like a bug? (therefore feature), but it’s pretty.. detailed.

When we create a nested scope within a larger one, the nested scope can access variables from the broader scope. So

#include <iostream>
#include <string>
using namespace std;

int main(){
  {
    const string s = "a string";
    cout << s << endl;
    {
      cout << s << " @ scope within"<< endl;
    }
   }

  return 0;
}

will output

a string
a string @ scope within

A const variable cannot be re-declared.

#include <iostream>
#include <string>
using namespace std;

int main(){
  {
    const string s = "a string";
    cout << s << endl;
    const string s = "b string";
    cout << s << endl;
    {
      cout << s << " @ scope within"<< endl;
    }
   }

  return 0;
}

will throw this error when compilation is attempted.

1-4_t.cpp: In function ‘int main()’:
1-4_t.cpp:9:18: error: redeclaration of ‘const string s’
     const string s = "b string";
                  ^
1-4_t.cpp:7:18: note: ‘const string s’ previously declared here
     const string s = "a string";
                  ^

Makes sense. A const variable isn’t supposed to change from the moment it is declared to the moment it is released from memory.

BUT THEN!!!! If we try re-declaring the variable within the scope..

#include <iostream>
#include <string>
using namespace std;

int main(){
  {
    const string s = "a string";
    cout << s << endl;
    {
      const string s = "b string";
      cout << s << " @ scope within"<< endl;
    }

   }

  return 0;
}

It compiles & runs without a problem

a string
b string @ scope within

Huh? So the variable value is inherited by a nested scope, but it’s const nature is somehow left out. If we try to identify what ‘s’ is after the end of the nested scope, we see that it is unchanged from before the nesting..

#include <iostream>
#include <string>
using namespace std;

int main(){
  {
    const string s = "a string";
    cout << s << endl;

    {
      const string s = "b string";
      cout << s << " @ scope within"<< endl;
    }
    cout << s << endl;

   }

  return 0;
}

Compiles and outputs

a string
b string @ scope within
a string

So the redefinition of ‘s’ within the nested scope doesn’t carry out of the scope. This isn’t very surprising, because we know that any definitions created within a scope is released from memory when the scope ends. I wonder they designed const variables to lose invariability (but not their value) when they enter a nested scope. Are there other properties changed when scope changes?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s