Prev: How to obtain a typedef for the unsigned version of a signed character type
Next: Does non- extern const have internal linkage?
From: forums_mp on 7 Mar 2010 12:08 Refencing this link: http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=41 Now quoting the standard: 'A name having namespace scope has internal linkage if it is the name of � an object, reference, function or function template that is explicitly declared static or, � an object or reference that is explicitly declared const and neither explicitly declared extern nor previously declared to have external linkage; or � a data member of an anonymous union. A name having namespace scope has external linkage if it is the name of � an object or reference, unless it has internal linkage; or � a function, unless it has internal linkage; or � a named class (clause 9), or an unnamed class defined in a typedef declaration in which the class has th etypedef name for linkage purposes; or � a named enumeration, or an unnamed enumeration defined in a typedef declaration in which the enumeration has the typedef name for linkage purposes; or � an enumerator belonging to an enumeration with external linkage; or � a template, unless it is a function template that has internal linkage (clause 14); or � a namespace, unless it is declared within an unnamed namespace.' So given: //test.h # ifndef TEST_H # define TEST_H # include <iostream> namespace { //int const dummy = 4 ; int dummy = 4 ; enum dummy { X, Y, Z } ; } class foo { public : foo () { std::cout << "foo: " << dummy << " " << X << std::endl; } }; class bar { public : bar () { std::cout << "bar: " << dummy << " " << Y << std::endl; } }; #endif # include "test.h" int main() { bar b; foo f ; std::cin.get(); } According to my interpretation of the standard the objects defined within the anonymous namespace has 'external linkage', however, if I did: namespace { int const dummy = 4 ; enum dummy { X, Y, Z } ; } Then the namespace would have (what) linkage? If memory serves enumerated types have external linkage. The const dummy variable has internal linkage so what does that make the anonymous namespace. Thanks in advance -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Nick Hounsome on 7 Mar 2010 16:05 On 8 Mar, 05:08, forums...(a)hotmail.com wrote: > Refencing this link: http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=41 I'm not entirely sure what you are getting at but your problem appears to be that you think that putting something in a header somehow makes it "more external". The actual compiling occurs after the preprocessing phase at which point there is no test.h just a single lump of code otherwise known as a single compilation unit. For this reason it is almost certainly a mistake to put an unnamed namespace or a static decl in a .h file. The only use that I can think of for doing so is the static initialisation trick used to make cin,cout & cerr available to code run before main which you should take a look at. (In outline <iostream> or some base header declares a static object whose ctor initializes the standard streams thus ensuring that they are always initialised before use provided that the header is included) -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: forums_mp on 8 Mar 2010 02:16 On Mar 8, 1:05 am, Nick Hounsome <nick.houns...(a)googlemail.com> wrote: > > I'm not entirely sure what you are getting at but your problem appears > to be that you think that putting something in a header somehow makes > it "more external". No. That's certainly not my problem at all. My 'problem' is two fold. a) What to with global constants - which led me to at least trying to understand anonymous namespaces b) Reconciling linkage information perused online (the link provided in my original post) relative to the standard > For this reason it is almost certainly a mistake to put an unnamed > namespace or a static decl in a .h file. Interesting! Good to know. This immediately implies that for a) above an anonymous namespace makes zero sense. -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Bart van Ingen Schenau on 8 Mar 2010 02:14 On Mar 8, 6:08 am, forums...(a)hotmail.com wrote: > Refencing this link: http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=41 > <snip> > namespace { > //int const dummy = 4 ; > int dummy = 4 ; > enum dummy { X, Y, Z } ; > } > <snip> > According to my interpretation of the standard the objects defined > within the anonymous namespace has 'external linkage', That is correct. > however, if I did: > > namespace { > int const dummy = 4 ; > enum dummy { X, Y, Z } ; > > } > > Then the namespace would have (what) linkage? If memory serves > enumerated types have external linkage. The const dummy variable has > internal linkage so what does that make the anonymous namespace. In the part of the standard that you quoted (snipped by me), the standard speaks about the linkage of a _name_. One of the key properties of an anonymous namespace is that it does not have a name, so it does not make sense to talk about the linkage of an anonymous namespace. If we change the example to: namespace dummy_ns { int const dummy_int = 4 ; enum dummy_enum { X, Y, Z } ; } then the names dummy_ns and dummy_enum have external linkage, while the name dummy_int has internal linkage. > > Thanks in advance > Bart v Ingen Schenau -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Seungbeom Kim on 12 Mar 2010 03:01
forums_mp(a)hotmail.com wrote: >> If we change the example to: >> namespace dummy_ns { >> int const dummy_int = 4 ; >> enum dummy_enum { X, Y, Z } ; >> } >> >> then the names dummy_ns and dummy_enum have external linkage, while >> the name dummy_int has internal linkage. > > Got it! Two questions: > 1) Given dummy_enum has 'extrnal linkage', I'm assuming that means the > name gets exported - which from my understanding means the name is > visible to all translation unit? Yes. > 2) Following up on Nicks response. Why is putting an unnamed > namespace in a header file a 'mistake'? I'm not Nick, but let me guess... The basic purpose of header files is to share something, but unnamed namespaces make their members unique to each translation unit. When the header file has an unnamed namespace and is included by multiple translation units, each will have its own copy of the members of the unnamed namespace. This is often not intended, is wasteful, and sometimes affects the correctness too: // f.h namespace { void f() { static std::ofstream logfile("/var/log/foo"); // use logfile } } // A.cc #include "f.h" // use f() // B.cc #include "f.h" // use f() Each of the translation units has its own copy of f(), so it is a waste of code space. Moreover, the static variable of f() is not shared, so each translation unit has its own copy. This is almost never intended; e.g. logfile will be constructed whenever it is called the first time in any translation unit, truncating the previous contents of the file. -- Seungbeom Kim [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |