Connecting Tech Pros Worldwide Help | Site Map

Using namespace across multiple files

Newbie
 
Join Date: Oct 2009
Posts: 4
#1: Oct 2 '09
The problem I have is basically the same as 'greentype' mentions at
<Link Removed>

I'm sharing variables through namespaces and a problem arises when I try to put my function definitions into a separate file.

Consider the following example, where I want to pass variable 'i', defined
in the main code, to the function a():

------------------------------
*** nn.h: ***
#ifndef _NN_H_
#define _NN_H_

namespace nn {
int i;
}
#endif

*** main.cpp ***
#include <iostream>
#include "nn.h"
using namespace std;
using namespace nn;

void a();

int main()
{
i=5;
a();
}

void a()
{
using namespace std;
using namespace nn;

i++;
cout << "i = " << i << endl;
}
------------------------------

But now if I put the definition of a() into a separate file ...

------------------------------
*** a.cpp ***
#include <iostream>
#include "nn.h"

void a()
{
using namespace std;
using namespace nn;

i++;
cout << "i = " << i << endl;
}
------------------------------

... then I get 'multiple definition' error when linking (g++ main.cpp
a.cpp -o main). If I make 'i' declaration in the header file 'extern' (as
suggested in other forums), I get 'undefined reference' error. I can compile when 'i' is declared as const in the header, but that's not what I want.

Any suggestions greatly appreciated.
Needs Regular Fix
 
Join Date: Jul 2008
Posts: 380
#2: Oct 2 '09

re: Using namespace across multiple files


linker complains because 'i' is delared, but never defined.
Declare it with extern in header, and define it (without 'extern') only once in some .cpp file
Expand|Select|Wrap|Line Numbers
  1. // in some .cpp file
  2. namespace nn {
  3. int i;
  4. }
  5.  
Banfa's Avatar
AdministratorVoR
 
Join Date: Feb 2006
Location: South West UK
Posts: 6,158
#3: Oct 2 '09

re: Using namespace across multiple files


This is nothing to do with namespaces. It is because you have declared i without the extern in the header file. The compiler treats this as a definition so the variable is defined in every source file you include the header in and you have multiple definitions of i.

By using the extern keyword

extern int i;

you are only declaring a, that is you inform the compiler that a variable a exists somewhere. You will then need to actually define a

int i;

in one of the source files.
Moderator
 
Join Date: Mar 2007
Location: North Bend Washington USA
Posts: 5,366
#4: Oct 2 '09

re: Using namespace across multiple files


Quote:

Originally Posted by Banfa

extern int i;

you are only declaring a, that is you inform the compiler that a variable a exists somewhere. You will then need to actually define a

int i;

in one of the source files.

Mostly correct.

Expand|Select|Wrap|Line Numbers
  1. extern int i;
declares that there is an int i with external linkage. It may be in this file or it may be in some other file.

For example, this is OK:
Expand|Select|Wrap|Line Numbers
  1. extern int i;
  2. int main()
  3. {
  4.     i = 10;
  5. }
  6. int i = 0;
Expand|Select|Wrap|Line Numbers
  1. extern int i = 0;
defines (creates) a variable int i with external linkage that has a value of 0. Other files can use this int i by coding extern int i.

When you place a value on your extern you actually create the variable. This is how you create sharable const values:

Expand|Select|Wrap|Line Numbers
  1. extern const int i = 10;
This creates a const int with a value of 10 that has external linkage. Other files can access this variable by coding:

Expand|Select|Wrap|Line Numbers
  1. extern const int i;
Newbie
 
Join Date: Oct 2009
Posts: 4
#5: Oct 2 '09

re: Using namespace across multiple files


Thank you guys for your replies, unfortunately none of that helps:

TO: newb16 & banfa: As I said, once I declare 'i' in the header as 'extern' and define it in main.cpp, a() in a.cpp doesn't know about it (undefined reference). And if I define 'i' in a() too, than I'm creating another variable, whereas I want to share (and change, if needed) the original one (defined in main.cpp).

TO: weaknessforcats: As I said, I don't want 'i' to be const. I want to be able to define it in main.cpp and share & change it (i++) in a.cpp. Which I can do as long as a() is in main.cpp, but not if I put it into a separate file, a.cpp.

Thanks,

Petr
Newbie
 
Join Date: Oct 2009
Posts: 4
#6: Oct 2 '09

re: Using namespace across multiple files


I see. Thank you guys. So if I understand this, the only way to get it to work is to make 'i' global, i.e. put the definition
'namespace nn { int i=5;}' in main.cpp, above int main() (and make the declaration 'extern', of course). But notice that in the original example (where function a() is in the SAME FILE as main()), 'i' was not global - I defined it within main(), yet still was able to share it with, and modify in, a() through the namespace. That is the framework I would like to retain, because I can't really make 'i' global, since it (and other variables I have and need to share) is CALCULATED in main() - I don't know their values in advance.

Petr
Expert
 
Join Date: Mar 2008
Location: Naperville, Illinois U.S.
Posts: 828
#7: Oct 2 '09

re: Using namespace across multiple files


Quote:

Originally Posted by PetrH View Post

... But notice that in the original example (where function a() is in the SAME FILE as main()), 'i' was not global - I defined it within main(), yet still was able to share it with, and modify in, a() through the namespace. That is the framework I would like to retain, because I can't really make 'i' global, since it (and other variables I have and need to share) is CALCULATED in main() - I don't know their values in advance.

If you want the same variable i to be accessible from two or more source files then it either has to be a global variable or you need to pass a pointer-to-i to function a(). This is not a namespace issue.
Banfa's Avatar
AdministratorVoR
 
Join Date: Feb 2006
Location: South West UK
Posts: 6,158
#8: Oct 3 '09

re: Using namespace across multiple files


Quote:

Originally Posted by PetrH View Post

But notice that in the original example (where function a() is in the SAME FILE as main()), 'i' was not global - I defined it within main(), yet still was able to share it with, and modify in, a() through the namespace. That is the framework I would like to retain, because I can't really make 'i' global, since it (and other variables I have and need to share) is CALCULATED in main() - I don't know their values in advance.

You have your terminology wrong.

In your original example i was global, but because you only had 1 source file that wasn't obvious. Any variable defined at file scope without the static specifier has global linkage, this is how you defined i and this is what caused the initial problem when you put that definition into 2 source files (though inclusion).

You don't define i in main() in your original example. You assigned to it. You still can with the proposed solution.

I can't quite tell what it is that makes you think i can't be global since it is and has been throughout all code examples and suggested solutions in this thread.

Of course you should be avoiding use of global variables in C++ (and in C for that matter but it a little harder with C), they are very bad practice.
Moderator
 
Join Date: Mar 2007
Location: North Bend Washington USA
Posts: 5,366
#9: Oct 3 '09

re: Using namespace across multiple files


Quote:

Originally Posted by PetrH

I see. Thank you guys. So if I understand this, the only way to get it to work is to make 'i' global, i.e. put the definition
'namespace nn { int i=5;}' in main.cpp, above int main() (and make the

I'm sorry. I didn't understand that you are using namespaces.

When you use a namespace you have to understand that a namespace is not like a struct. That is, there is no single place you can go to see what's in the namespace. It's what they call an open-ended definition->Things are in the namespace if you say so.

In this case in a .cpp file, say Data.cpp put your namespace that defines the int:

Expand|Select|Wrap|Line Numbers
  1. Data.cpp
  2. namespace Stuff
  3. {
  4.     int i = 0;
  5. }
Then write a header file Data.h:

Expand|Select|Wrap|Line Numbers
  1. namespace Stuff
  2. {
  3.     extern int i;
  4. }
Then in main.cpp you can access the int:

Expand|Select|Wrap|Line Numbers
  1. #include <Stuff.h>
  2. int main()
  3. {
  4.     cout << Stuff::i;
  5. }
Of course this assumes that Data.cpp and main.cpp are both in your build.

If you read up on anonymous namespaces you will find out how to do away with the name Stuff altogether.
Newbie
 
Join Date: Oct 2009
Posts: 4
#10: Oct 5 '09

re: Using namespace across multiple files


Thank you guys. I get it now.
Reply