variables inside namespace

Dear formum members,

I have a rather strange problem when trying to define variables inside a namespace. My original idea was to use those variable names and in various functions of the c++ code. I did very simple definition of my variables in nstest.h as follows

1
2
3
4
5
6
#ifndef NSTEST_H
#define NSTEST_H
namespace nstest {
Int var1;
Int var2;
}


If I later on include this file in the main as follows:
1
2
3
4
#unclude “nstest.h”
Using namespace nstest;
Int main() {
…

I can compile and run. However if I try to use the same procedure in one f my functions I get violation of the “one definition rule”.
1
2
3
4
nsf.o:(.bss+0x0): multiple definition of `nstest::var1'
main.o:(.bss+0x0): first defined here
nsf.o:(.bss+0x4): multiple definition of `nstest::var2'
main.o:(.bss+0x4): first defined here

My obvious guess would be to use extern int var1 ; for my variables in the namespace. However this produces an error likewise.
1
2
3
4
5
main.cpp:(.text+0x976): undefined reference to `nstest::var1'
main.cpp:(.text+0x97c): undefined reference to `nstest::var2'
nsf.o: In function `nsf(int, int)':
nsf.cpp:(.text+0x1a): undefined reference to `nstest::var1'
…..


My general idea of doing this was to see what are the differences between the namespaces and Fortran modules. In Fortran it is possible to have module files, which can contain functions, names and variables. If you include them in some of your functions or in the main, you have access to everything that is contained inside them.

I don't understand why this makes problems, I have used the same method to define classes inside a namespace, and no problems occurred. I guess that I have some misunderstanding about the namespaces. I would be very grateful if someone can help me understand what am I doing wrong.

Thanks,

Last edited on
Try the following. In the header write

extern int var1;
extern int var2;

In the main module after the header write

int nstest::var1;
int nstest::var2;
Hi Vlad,

I have tried this option already. However, it produces the error listed at the end of my original post. I know that if you write variable definitions before int main { .. this makes the variables global. Maybe, this is the problem. I tried the following options
1
2
3
4
 
int main () {
use namespace nstest;
….  

Unfortunately, I run into the same problem of multiple definitions.
I think that you are doing something another than I said. One more in the header in the namespace write

extern int var1;
extern int var2;

In the main module after the header write

int nstest::var1;
int nstest::var2;

Or show your code.
Last edited on
closed account (o1vk4iN6)
It looks like you used the extern symbol in main.cpp, but you don't want to use it there you want to define it there, that's why it is giving undefined reference.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

// -------------- test.h

extern int c;

// -------------- main.cpp

#include "test.h"

extern int a;
int b;

int main(int, const char**)
{
     a = 10; // undefined reference
     b = 5; // ok
     c = 2; // ok
}

// just to show it uses the "c" from test.h we define it after main
int c = 3; // any other file that includes "test.h" will be referencing this var



Inorder for "extern" to work the variable has to be defined somewhere in a source file (usually .cpp).
Last edited on
Ok in general, suppose I would like to define namespace, have some variables in this namespace and then I would like to put.
1
2
3
namespace nstest {
int var1,var2,var3,var4;
}

And use it in my functions and in the main. That should be fairly simple. However I am missing something and I run into troubles. For completeness I give the source code of my main the function and the header file containing the namespace.
In nstest.h I define the namespace:
1
2
3
4
5
6
7
#ifndef NSTEST_H
#define NSTEST_H
namespace nstest {
int  var1;
int  var2;
}
#endif 

The main is defined as such:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>
#include <cstdlib>
#include "a.h"
#include "b.h"
#include "f.h"
#include "matt.h"
#include <vector>
#include "nstest.h"
#include "nsf.h"

using namespace std;
using namespace na;
using namespace nb;
using namespace nf;
using namespace nstest;
int main () {


In the header nsf.h I have the definition of my function. The function body is defined as follows:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <iostream>
#include "nstest.h"
#include "a.h"

using namespace std;
using namespace nstest;
using namespace na;



void nsf(int i, int j) {



cout << "var1 "<<nstest::var1<<endl;

cout << "var2 "<<nstest::var2<<endl;

nstest::var1 = i;
nstest::var2 = j ;



}


Thanks,
Last edited on
How many times I shall repeat the same?!!!

in the header in the namespace write

extern int var1;
extern int var2;

In the main module after the header write

int nstest::var1;
int nstest::var2;

Are you able to do what I showed?!!!
Vlad,
I did it and it produced the error which is quoted in my original file. In what I posted above, I have removed the extern, since it produced error. Thanks anyway for your super valuable comments.

Btw what is the meaning of what you propose? Why defining the classes in a namespace and then, using it in different routines is ok. Here defining this simple integer variables makes problems.

For instance I made an experiment with the following class
header:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#ifndef A_H
#define A_H

using namespace std;


namespace na {

class A {

int x;

public:
A() ;
A(int) ;
~A();
int get_a() ;
void show_ns() ;
} ;

 }

#endif


and the a.cpp file reads as follwos:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <iostream>
#include "a.h"


using namespace std;
using namespace na;


namespace na {

A::A(int i) { x=i; }

A::~A(){ cout<<"destructor A"<<endl; }

A::A() {x = 555;}

void A::show_ns()
{
cout << "Void show A" <<endl;

}

int A::get_a() { return x; }

}


This I can "use namespace na " at will, and I do not need any modifications?
Last edited on
Well if you have only one module then I do not see the reason of the error message.
In this case try to write a simple example that everybody could copy and paste it and then compile it to reproduce the error.

Last edited on
If you have only one module then it looks like somewhere in another header you declared the same variables in the same namespace.
Last edited on
Well,
Can you explain me why in the case of a class, inside a namespace by just defining it inside, as I showed in one of my previous posts. Subsequently can call it in all the functions by writing “use namespace class”.
However, if I define simple variables I have to put "extern", and then define
1
2
int nstest::var1;
int nstest::var2;

However if I define variables before the main i make them global. Maybe this is not always desired.
Let at first find the reason of your error. As for your question I have not understood it.
You have to put the extern specifier if a variable is used in several modules and only one its definition shall be.
That to be more clear what I meant I wil show an example.

Let assume you have two modules

A.cpp

1
2
3
4
5
6
namespace N1
{
   int x;
}

// some other stuff 


B.cpp

1
2
3
4
5
6
namespace N1
{
   int x;
}

// some other stuff 


In this case you have two definitions of the same variable x in two modules because statement int x; is a definition.

However if you wrote

namespace N1
{
extern int x;
}

then extern int x; is not a definition of a variable. It is a declaration. To define it you can write only in one module either

namespace N1
{
int x;
}

or

int N1::x;



Well,
I think that I figured out what is going on. The variables, which are declared inside my namespace nstest are declared outside any function body, so they have to be with external linkage. Once defined, those variables can be used inside the functions. This is exactly what is done in the following peace of code.
1
2
3
4
5
using namespace nstest; 
// after all it works perfect for functions and classes.
int nstest::var1;  // this variable is defined here
int nstest::var2; // this variable is defined here
int main () {

What this does is to tell the compiler that the variables var1,var2 are defined here and at the other places they are just referenced. Typing this in the main is not so much clever, it is better to define a separate *.cpp file for this purpose: nstest.cpp
1
2
3
Namespace nstest {
Int var1,var2
}  


Everywhere where “extern” is sitting before the variable, this tells the compiler that we have kind of a variable which is defined elsewhere. After this we just “ include “ the header containing the namespace and “use ” the namespace and everything works as a piece of cake.

I do not fully understand what the header file is needed for. It looks like that it contains some sort of prototypes of the variables similar to how functions are prototyped.

Last edited on
A header file is needed if its declarations are shared by several modules. If you want that apart from function declarations some other variable declarations should be shared by several modules you place them in a header. But in this case the header shall contain only declarations of variables without their definitions. The definitions shall be placed only in one module otherwise the one definiton rule will be broken.
I think that I got the idea. C++ is quite peculiar language, life is much easier with Fortran.
They are different tools for different tasks.

Sometimes I encounter C++ code written by people who are clearly thinking in Fortran. It's horrific. You will do yourself no favours whatsoever if you try to think of C++ in terms of things you know from Fortran.
Topic archived. No new replies allowed.