From: forums_mp on
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
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
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
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
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! ]