Accessing a global variables within nested namespaces - c++

I am quite new to c++ and having trouble with namespaces.
#include <iostream>
int x = 10;
namespace ns {
int x = 5;
namespace ns_nested {
int z = x; //z is assigned a value of 5??
}
}
int main(){
std::cout << ns::ns_nested::z;
}
This prints 5. Initially, I thought this was because I was just changing the value of x to 5 from 10.
But if I change the first declaration of x to const int x = 10, it still prints 5.
So, my question here is twofold:
I though the variables declared in a global scope was... well... global, as in just one instance of it was available to all. So, why/how am I able to declare an instance of a variable with the same name again?
If I were to assign the value of z to the value of x that was declared globally instead of the one in the outer namespace, how would I do it?

1) I though the variables declared in a global scope was... well... global, as in just one instance of it was available to all. So, why/how am I able to declare an instance of a variable with the same name again?
namespace ns {
int x = 5;
namespace ns_nested {
int z = x; //z is assigned a value of 5??
}
}
here x is not global namespace it is under namespace ns
2)If I were to assign the value of z to the value of x that was declared globally instead of the one in the outer namespace, how would I do it?
see this you may got an idea
#include <iostream>
const int x = 10;
namespace ns
{
int x = 5;
namespace ns_nested
{
int z1 = ::x; //global namespace
int z2 = ns::x; //ns namespace
}
}
int main()
{
std::cout << ns::ns_nested::z1<<std::endl;
std::cout << ns::ns_nested::z2<<std::endl;
}

Related

How do namespace's with same name but different scope (e.g. foo, bar::foo) work?

If there are two namespaces named Foo and Bar and there is a namespace named Foo inside Bar. If I refer to a variable Foo::i from inside Bar will it search for i in both Foo and Bar::Foo. If not, is it possible to make the compiler search in both namespaces when i doesn't exist in Bar::Foo?
More concrentely in the below example, I am trying to refer variable i from namespace a in b without puting extra ::. I know putting :: works, I am trying to see if there is any other way to resolve this.
#include <iostream>
#include <string>
namespace a {
int i = 1;
}
namespace b {
namespace a {
}
namespace c {
int j = a::i; // Doesn't work, need to use ::a::i;
}
}
int main()
{
std::cout << b::c::j << "\n";
}
If you can change b::a, then you can indeed make certain declarations available in b::a from ::a as fallbacks:
namespace a {
int i = 1;
int j = 2;
}
namespace b {
namespace a {
namespace detail {
using ::a::i; // Selectively bring declarations from ::a here
}
using namespace detail; // Make the names in detail available for lookup (but not as declarations).
//int i = 2;
}
namespace c {
int j = a::i; // Uses ::a::i
// int k = a::j; // ERROR! We didn't bring ::a::j into b::a at all
}
}
Here it is live.
Un-commenting the declaration of b::a::i will change the output. Since a proper declaration takes precedence over names brought in by a namespace using directive.
You could explicitly have a using declaration in the inner namespace for variables that it wants to use from the outer one.
i.e. for your example,
namespace a {
int i = 1;
}
namespace b {
namespace a {
using ::a::i; //inner one does not define its own
int i2 = 2; //inner one creates its own variable
}
namespace c {
int j = a::i; // Doesn't work, need to use ::a::i;
}
}
See:
https://en.cppreference.com/w/cpp/language/namespace#Using-declarations

Variable declaration in C++ within namespaces

In a library I am working with some variables are declared like that:
char &ns::x = y;
However, if I do it that way I get the following error:
error: no member named 'x' in namespace 'ns'
If I rewrite it, it works:
namespace ns {
char &x = y;
}
What exactly is the difference? And why is it working within the library?
If you’re right and the code from the library is exactly as written, then this implies that elsewhere in this library, you’ll find the following declaration:
namespace ns {
extern char& x;
}
In other words, x must have already been declared (and not defined!) inside ns.
The first declaration
char &ns::x = y;
assumes that the name x is already declared in the namespace ns. However this assumption is wrong (in the provided code snippet there is no previous declaration of the variable. Possibly the code snippet is not complete.).
The code snippet can works provided that the variable x is already declared (without its definition) in the namespace ns.
For example
#include <iostream>
namespace ns
{
extern char &x;
}
char y;
char & ns::x = y;
int main() {
return 0;
}
In this code snippet
namespace ns {
char &x = y;
}
there is defined a reference that is initialized by the object y.
The Variable declaration using namespace:
#include <iostream>
using namespace std;
// Variable created inside namespace
namespace first
{
int val = 500;
}
// Global variable
int val = 100;
int main()
{
// Local variable
int val = 200;
// These variables can be accessed from
// outside the namespace using the scope
// operator ::
cout << first::val << '\n';
return 0;
}

How do you set a global int inside of a void in C++?

I am making a stat code console app in, C++ visual studio 2013.
I have global intx set as far as I know, and I have some voids made up, the problem is I'm unsure how to set the new global int inside of the void and reuse the int (updated) inside of int main.
please help.
#include < iostream>
using namespace std;
int x = 0;
void change(int x);
void change2(int x);
int main ()
{
change;
system("PAUSE");
change2;
return(0);
}
void change(int x)
{
x = 5;
cout << x << endl;
}
void change2(int x)
{
x = (5 + 1);
cout << x << endl;
}
I think thats a simplified version
Your parameter int x hides the global variable int x, that is why the function doesn't change the global.
You can easily avoid this problem by using different names for each declared variable.
okay, let's look at your code ...
#include <iostream>
using namespace std;
int x = 0; // a global variable.
void change(int x); // declares a function taking an int, returning void
void change2(int x); // declares another function with same signature
int main ()
{
change; // declare a reference to function change()
// no function call: statement has no effect
system("PAUSE");
change2; // declare a reference to function change2()
// no function call: statement has no effect
return(0);
}
void change(int x) // defines a previously declared function
{ // argument x is passed by copy
x = 5; // sets local variable x to 5
cout << x << endl; // global variable x is not affected
}
void change2(int x) // defines another previously declared function
{ // argument x is passed by copy
x = (5 + 1); // sets local variable x to 5+1
cout << x << endl; // global variable x is not affected
}
If you want to change the global variable x, then you must not hide it with a local variable (or explicitly change the global variable):
int x; // global variable
void change_x_to(int i)
{
x=i; // assigns local variable i to global variable x
}
void change2_x_to(int x)
{
::x=x; // assigns local variable x to global variable x
}
int main ()
{
change_x_to(5);
change2_x_to(x+1); // the global x (of course)
assert(x==6);
} // return 0; is automatically created for main()
A scope is a region of the program and broadly speaking there are three places, where variables can be declared:
Inside a function or a block which is called local variables,
Outside of all functions which is called global variables.
You cannot declare a global variable inside a local block although,ye you can use a static global block which can hold the last modified value of your variable.
#include "example.h"
int global_foo = 0;
static int local_foo = 0;
int foo_function()
{
/* sees: global_foo and local_foo
cannot see: local_bar */
return 0;
}
Even his approach is not a good programming practice rather If global variable is to be used across multiple .c files, you should not declare it static. Instead you should declare it extern in header file included by all .c files that need it.
Refer this for further details.

User-declared namespace member

There is from 3.4.1/14:
If a variable member of a namespace is defined outside of the scope of
its namespace then any name that appears in the definition of the
member (after the declarator-id) is looked up as if the definition of
the member occurred in its namespace.
If that name treated as the definition of the member name then what is it point of declaration?
And why the following example will works:
namespace N
{
extern int j;
}
int i = 2;
int N::j = i; //N::j=2
int N::j=i actual appears into the namespace scope. Hence the declarationint i=2 is not visible for unqualified name lookup. Why does this declaration found?
Your question:
int N::j=i actual appears into the namespace scope. Hence the declaration int i=2 is not visible for unqualified name lookup. Why does this declaration found?
Answer:
Since i is not found in the N namespace, it is looked up in the global namespace. Had an i been there in the N namespace, that would have been used to initialize N::j.
Hope the following program clarifies your doubt.
#include <iostream>
namespace N
{
extern int j;
extern int k;
int x = 3;
}
int x = 2;
int y = 10;
int N::j = x; // N::x is used to initialize N::j
int N::k = y; // ::y is used to initialize N::k
int main()
{
std::cout << N::j << std::endl;
std::cout << N::k << std::endl;
}
Output:
3
10
Update, in response to comment by OP
What the standard is saying is that:
namespace N
{
extern int j;
}
int x = 2;
int N::j = x;
is equivalent to:
namespace N
{
extern int j;
}
int x = 2;
namespace N
{
int j = x;
}
The logic for lookup ofx is same. If it is found within the same namespace N, it is used. If x is not found in namespace N, it is searched for outward in the enclosing namespaces.
You seem to be confused about how name lookup works on a basic level. Maybe a simple example helps:
#include <iostream>
void print(std::string const & s) { std::cout << "Boo: " << s << "\n"; }
namespace Foo
{
std::string message = "Foo";
void action() { print(message); }
}
int main() { Foo::action(); }
Clearly the name print is visible in the definition of Foo::action. Names from containing namespaces are visible in contained namespaces. There's nothing unusual about that.
The point of the rule you are quoting, and which R Sahu already demonstrated nicely, is that you can put the definition of a variable elsewhere from its declaration, and in that case any name appearing in the initializer is looked up in the namespace in which the variable is declared. Here's another example:
namespace Foo
{
namespace Bar { int a = 10; }
int b = 20;
extern int c;
}
namespace Bar { int a = -20; }
int b = 5;
int Foo::c = Bar::a + b; // uses Foo::Bar::a and Foo::b, NOT ::Bar::a or ::b
int main() { return Foo::c; } // returns 30

Accessing member of an unnamed namespace when the outer namespace has a member with the same name

Here is the test code
extern "C" {int printf(const char *, ...);}
namespace PS
{
int x = 10; // A
// some more code
namespace {
int x = 20; // B
}
// more code
}
int main()
{
printf("%d", PS::x); // prints 10
}
Is there any way to access inner(unnamed) namespace's x inside main?
I dont want to change code inside PS. Apologies if the code looks highly impractical.
P.S: I tend to use the name x quite often.
No. The only way to specify a namespace is by name, and the inner namespace has no name.
Assuming you can't rename either variable, you could reopen the inner namespace and add a differently-named accessor function or reference:
namespace PS {
namespace {
int & inner_x = x;
}
}
printf("%d", PS::inner_x);
One way is to add this code:
namespace PS
{
namespace
{
namespace access
{
int &xref = x;
}
}
}
and then you can access what you want:
std::cout << PS::access::xref << std::endl; //prints 20!
Demo : http://ideone.com/peqEs