Q:

Passing global variables as const reference

The following code compiles and works. The value displayed of both a and n are 4.
#include <iostream>
using namespace std;

int a = 2;

void foo(int const&n)
{
    a = n*2;
    cout<<"a = "<<a<<"  n = "<<n<<endl;
}

int main()
{
    foo(a);
}
OUTPUT: a = 4  n = 4

Why does the compiler not complain about n being a const reference? For example, the following code fails to compile.
#include <iostream>

using namespace std;

int a = 2;

void foo(int const&a)
{
    a = a*2;
    cout<<"a = "<<a<<endl;
}

int main()
{
    foo(a);
}
OUTPUT:  In function 'void foo(const int&)':
10:7: error: assignment of read-only reference 'a'

How are the two cases different ?

A:

In the first case you're assigning to a global variable a. n changes because it's a reference to the mutable global variable. Changing a is allowed, but changing n directly is forbidden.
In the second case you're trying to re-assign to the const argument a. This is forbidden as a is const.
What you've done is shadow global variable a with a local variable. In the second example, within foo the global variable named a does not exist, instead there's an argument that occupies that name.

