C ++: binding external variables from namespace

I cannot reference an external variable from the namespace using extern . It works from a global scope, but as soon as the namespace is thrown there, it does not bind.

My const file looks like this:

StringConstants.cpp

 #include "MyString.h" MyString test1("string1"); MyString test2("string2"); 

The main program is as follows:

main.cpp

 #include <stdio.h> #include "MyString.h" extern MyString test1; namespace { extern MyString test2; } int main(void) { printf("%s\n", test1.Str()); printf("%s\n", test2.Str()); } 

I get similar errors in both GCC and Visual Studio:

 gcc main.o StringConstants.o -o main main.o:main.cpp:(.text+0x49): undefined reference to `(anonymous namespace)::test2' collect2: ld returned 1 exit status 1>Linking... 1>main.obj : error LNK2001: unresolved external symbol "class MyString `anonymous namespace'::test2" ( ?test2@ ?A0x0df4aa01@ @ 3VMyString@ @A) 1>C:\p4\namespace_repro\namespace_repro2\Debug\namespace_repro2.exe : fatal error LNK1120: 1 unresolved externals 

I tried qualifying the reference to test2 ( extern MyString ::test2 ), but it just thinks test2 is a static member of MyString. A named namespace does not behave differently than anonymous. For various reasons, we don’t want to remove namespaces or put external elements outside of namespaces.

Here are other files for completeness:

MyString.h

 class MyString { public: MyString(const char* str): mStr(str) {}; const char* Str() const { return mStr; } private: const char* mStr; }; 

Makefile

 CC=gcc CFLAGS=-Wall main: StringConstants.o main.o 

The goals of this system are that constants are all defined in one file and that they are solved during communication, and not in the header. It seemed that the above code would work, but since it was rejected by two different linkers, it seems that my understanding of C ++ is not enough. Advice on how to make it work, besides putting external external spaces?

+4
source share
2 answers

$ 7.3.1 / 2 - "Each name first declared in a namespace is a member of this namespace."

This means that the name test2 is part of the anonymous namespace and must be defined in this namespace if used.

This is not a problem with an anonymous namespace, but in any case, any namespace.

+4
source

What...

 namespace { extern MyString test2; } 

... is says that test2 must exist in the anonymous namespace, but it is not - it is in the global namespace. You lie to your compiler, so it generates an object that will not bind. You need the extern declaration to be made from the same scope of the namespace as the variable.

BUT, there should be StringConstants.h, which should include main.cpp, so that the compilation unit knows about the strings without any additional statements.

+5
source

All Articles