Namespaces with external linkage

删除回忆录丶 提交于 2019-12-28 13:59:02

问题


The problem I have is basically the same as 'greentype' mentions at http://www.cplusplus.com/forum/beginner/12458/

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.


回答1:


Any global object, like i, must have exactly one definition somewhere in the program, but it can be declared multiple times.

Using extern without an initializer makes a declaration just a declaration. This is appropriate for your header file, but you must still define i somewhere. As well as making the header declaration extern you also need to add a definition (i.e. a copy of the declaration without extern) to one and only one of your source files.

Edit: Reading your question, you say that you want to pass a variable to a function. From a style and code structure point of view, this isn't usually a good reason for using a shared (global) variable. In the absence of any overriding reasons you should normally define a function which takes a parameter and pass a value (possibly from a local variable) from the calling site to that function via its parameter.




回答2:


The header file should say:

namespace nn {
    extern int i;
}

This is a "declaration" not a "definition". You then want a definition in one and only one file:

namespace nn {
    int i = 1;
}

Of course, a much better approach is just to not have globals at all.




回答3:


This has nothing really to do with namespaces, and all to do with the linkage, external or otherwise of the symbol i in your various examples. By default, global variables have extern linkage, while global const symbols have static linkage - this explains why it works when you make i const. To resolve your problem, one way is to declare i with extern linkage in the header file, then define it in only one of the implementation files, as shown below:

header:

extern int i;

a.c:

int i:

main.c:

int main()
{
  i = 1; // or whatever
}

Note that I have removed the namespace for clarity - the end result is the same.



来源:https://stackoverflow.com/questions/1508081/namespaces-with-external-linkage

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!