Global Scope VS Global Namespace

Global scope vs global namespace

In C++, every name has its scope outside which it doesn't exist. A scope can be defined by many ways : it can be defined by namespace, functions, classes and just { }.

So a namespace, global or otherwise, defines a scope. The global namespace refers to using ::, and the symbols defined in this namespace are said to have global scope. A symbol, by default, exists in a global namespace, unless it is defined inside a block starts with keyword namespace, or it is a member of a class, or a local variable of a function:

int a; //this a is defined in global namespace
//which means, its scope is global. It exists everywhere.

namespace N
{
int a; //it is defined in a non-global namespace called `N`
//outside N it doesn't exist.
}
void f()
{
int a; //its scope is the function itself.
//outside the function, a doesn't exist.
{
int a; //the curly braces defines this a's scope!
}
}
class A
{
int a; //its scope is the class itself.
//outside A, it doesn't exist.
};

Also note that a name can be hidden by inner scope defined by either namespace, function, or class. So the name a inside namespace N hides the name a in the global namspace. In the same way, the name in the function and class hides the name in the global namespace. If you face such situation, then you can use ::a to refer to the name defined in the global namespace:

int a = 10;

namespace N
{
int a = 100;

void f()
{
int a = 1000;
std::cout << a << std::endl; //prints 1000
std::cout << N::a << std::endl; //prints 100
std::cout << ::a << std::endl; //prints 10
}
}

C++: using directive statement in main function Vs global scope

[namespace.qual]/1:

Qualified name lookup in a namespace N additionally searches every element of the inline namespace set of N ([namespace.def]). If nothing is found, the results of the lookup are the results of qualified name lookup in each namespace nominated by a using-directive that precedes the point of the lookup and inhabits N or an element of N's inline namespace set.

In the first case, using namespace nspace; inhabits the block scope inside the main function, so it is not considered.

In the second case, using namespace nspace; inhabits the global namespace scope, so it is considered by lookup in the global scope.

Why are these global variables when they have namespace scope?

Global roughly means accessible from every translation unit, no matter if the variable is in a namespace or not. The best example is std::cout, which is a global variable defined in namespace std, and which represents an instantiation of std::basic_ostream<>.

Regarding your second question, Constants::pi is accessible because you include the header globals.h, which declares extern const double Constants::pi;. This declaration instructs the compiler that the variable has external linkage, and it is your responsibility to define it in some .cpp file (which you do in globals.cpp)1). So the linker is able to find the symbol in the globals.cpp, and that's it.


1) Note that you can even provide the definition extern const double pi = 3.14; directly in the header file, but it is not recommended, since including the header in multiple translation units will lead to a duplicate symbol.

When to use :: for global scope in C++?

I use it quite infrequently; only when some ambiguity needs resolving for whatever reason. This is pretty subjective, though.

There may be some occasions (say, inside a template) where you're worried about ADL causing ambiguities only in certain cases:

template <typename T>
void foo(T t)
{
::bar(t); // :: just in case there's a `bar` in `T`'s namespace
}

Confusion About C++ Global Namespace

using namespace Foo; brings all the contents of namespace Foo into the context of the current namespace.

Since namespace Bar is among the contents of namespace Foo and the current namespace on the line with the using statement is the global namespace, namespace Bar is brought into the context of the global namespace.

Python Global Namespace values

When you type my_var in your code, Python needs to know what that represents. First it checks in locals and if it doesn't find a reference it checks in globals. Now Python can evaluate your code when you right 'string' == my_var. Similarly, when you write the name of a function in your code, Python needs to know what that represents. Since the output of a function can change based on the input, Python can't store a simple value like a string to represent a function in globals. Instead it stores the memory reference so that when you type my_func(), it can go to that memory store and use the function to compute the output.



Related Topics



Leave a reply



Submit