Anonymous namespace clarifications

589 views
Skip to first unread message

Klaim - Joël Lamotte

unread,
Feb 4, 2013, 4:51:02 AM2/4/13
to std-dis...@isocpp.org
Hi, I think I need some clarification on the intended behavior of anonymous namespace.

First, can someone confirm me that an object in an anonymous namespace in a unique cpp is equivalent to defining it static? Or should I add always static anyway?

Second, I just tried to write a constant in an anonymous namespace, but defined in a header.
I first thought that I would have a multiple symbol definition error on link but both GCC4.7 and VS2012 seem to compile and link it fine (the code: https://compilr.com/klaim/test-anonymous-namespace/).
My guess is that the object is redefined in each cpp using it.
Is it supposed to be allowed by the standard or is it undefined behaviour?


Joel Lamotte


Johannes Schaub

unread,
Feb 4, 2013, 4:57:55 AM2/4/13
to std-dis...@isocpp.org

It is not redefined. But a different object is defined each time.

That is fine. As you probably already know, C++ allows more than one object to be defined.

As to the "why" they are different: Both the const and the unnamed namespace orthogonally give the variable internal linkage.

Daniel Krügler

unread,
Feb 4, 2013, 5:03:55 AM2/4/13
to std-dis...@isocpp.org
2013/2/4 Klaim - Joël Lamotte <mjk...@gmail.com>:
> Hi, I think I need some clarification on the intended behavior of anonymous
> namespace.

Note that the original intention was different, because some rules
have been changed. Originally "static" as variable or function
specifier in namespace scope was deprecated and unnamed namespace were
recommended as replacement. Note that in C++03 variables in unnamed
namespace did have external linkage, because that was needed to allow
them as template arguments.

These rules have been changed in C++11: Static specifiers for
namespace scope declarations are no longer deprecated and unnamed
namespaces and their contents have internal linkage (similar as
variables declared as static in namespace scope), modulo some wording
glitches such as
http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1544.

> First, can someone confirm me that an object in an anonymous namespace in a
> unique cpp is equivalent to defining it static? Or should I add always
> static anyway?

It doesn't matter any more.

> Second, I just tried to write a constant in an anonymous namespace, but
> defined in a header.
> I first thought that I would have a multiple symbol definition error on link
> but both GCC4.7 and VS2012 seem to compile and link it fine (the code:
> https://compilr.com/klaim/test-anonymous-namespace/).
> My guess is that the object is redefined in each cpp using it.
> Is it supposed to be allowed by the standard or is it undefined behaviour?

It is well-defined, because of the semantics of unnamed namespaces
being defined as equivalent to

namespace /unique/ { }
using namespace /unique/;
namespace /unique/ { /namespace-body/ }

This means, it will have a different (unique) namespace for each
header in a different translation unit, so will there be a different
variable for each translation unit.

- Daniel

Klaim - Joël Lamotte

unread,
Feb 4, 2013, 5:15:18 AM2/4/13
to std-dis...@isocpp.org
Thank you both, this is very clear and helpful.

Now may I ask if you know cases where anonymous namespace in a header
is very useful?
The first thing I think about is constants definitions in one header instead of cpp+header, but I don't really see an advantage.

Is it used for some specific purpose or is it a side effect of the standard rules?

Joel Lamotte

Daniel Krügler

unread,
Feb 4, 2013, 5:17:16 AM2/4/13
to std-dis...@isocpp.org
2013/2/4 Klaim - Joël Lamotte <mjk...@gmail.com>:
As I said: You would use it wherever you would have used a static
declaration in namespace scope.

- Daniel

Klaim - Joël Lamotte

unread,
Feb 4, 2013, 5:20:50 AM2/4/13
to std-dis...@isocpp.org

On Mon, Feb 4, 2013 at 11:17 AM, Daniel Krügler <daniel....@gmail.com> wrote:
As I said: You would use it wherever you would have used a static
declaration in namespace scope.

In a header?? O__o
Maybe I'm missing something here.

Joel Lamotte

Johannes Schaub

unread,
Feb 4, 2013, 5:23:38 AM2/4/13
to std-dis...@isocpp.org


Am 04.02.2013 11:15 schrieb "Klaim - Joël Lamotte" <mjk...@gmail.com>:
>
> Thank you both, this is very clear and helpful.
>
> Now may I ask if you know cases where anonymous namespace in a header
> is very useful?
> The first thing I think about is constants definitions in one header instead of cpp+header, but I don't really see an advantage.
>

Unnamed namespaces should only be used in a header for data (but i still prefer just declaring them "const"). And only when the data in it is const.

Mutable data wont carry modifications outside a TU which is bad if the declaration was in a header.

And for functions, making them static or in an unnamed namespace easily will bloat the executable. Either make it inline, so that you have only one function. Or define it in the cpp file (which we want to avoid for the purpose of discussion).

And for classes, the reasoning is the same as fir nonconst data. If they are ina header, they ought to have extern linkage and be the same for every inclusion. Otherwise, put it not in a header.

Another good argument for not splitting const data up into a cpp file is avoiding the static initialization order fiasco that happens when you use the data value in the initialization of another nonlocal nonmember object.

Klaim - Joël Lamotte

unread,
Feb 4, 2013, 5:28:16 AM2/4/13
to std-dis...@isocpp.org



On Mon, Feb 4, 2013 at 11:23 AM, Johannes Schaub <schaub....@googlemail.com> wrote:


Unnamed namespaces should only be used in a header for data (but i still prefer just declaring them "const"). And only when the data in it is const.

Mutable data wont carry modifications outside a TU which is bad if the declaration was in a header.

And for functions, making them static or in an unnamed namespace easily will bloat the executable. Either make it inline, so that you have only one function. Or define it in the cpp file (which we want to avoid for the purpose of discussion).

And for classes, the reasoning is the same as fir nonconst data. If they are ina header, they ought to have extern linkage and be the same for every inclusion. Otherwise, put it not in a header.

Another good argument for not splitting const data up into a cpp file is avoiding the static initialization order fiasco that happens when you use the data value in the initialization of another nonlocal nonmember object.


Ok so basically anonymous namespace in headers IS interesting with const data/objects but not in other cases.

Thanks for the clarification.

Joel Lamotte

FrankHB1989

unread,
Feb 13, 2013, 7:30:45 AM2/13/13
to std-dis...@isocpp.org


在 2013年2月4日星期一UTC+8下午5时51分02秒,Klaim - Joël Lamotte写道:

I think what you discussed should be "unnamed namespace"(a namespace to be given a unique name), not "anonymous namespace"(the global namespace is also "anonymous" but cannot be named).

The linkage rules about namespaces are not only for names of const variables:

3.5 Program and linkage [basic.link]
3 A name having namespace scope (3.3.6) has internal linkage if it is the name of
— a variable, function or function template that is explicitly declared static; or,
— a variable that is explicitly declared const or constexpr and neither explicitly declared extern nor
previously declared to have external linkage; or
— a data member of an anonymous union.
4 An unnamed namespace or a namespace declared directly or indirectly within an unnamed namespace has
internal linkage. All other namespaces have external linkage. A name having namespace scope that has not
been given internal linkage above has the same linkage as the enclosing namespace if it is the name of
— a variable; or
— a function; or
— a named class (Clause 9), or an unnamed class defined in a typedef declaration in which the class has
the typedef name for linkage purposes (7.1.3); or
— a named enumeration (7.2), or an unnamed enumeration defined in a typedef declaration in which the
enumeration has the typedef name for linkage purposes (7.1.3); or
— an enumerator belonging to an enumeration with linkage; or
— a template.

You can see that the explicit use of 'static' to specifying internal linkage is only one of these cases. The const(and constexpr) variable is another case.

PS. For C++03 code, the names within unnamed namespaces would probable be having external linkage. This could bloat the executable even for using in non-headers, but should be easily optimized(e.g.http://gcc.gnu.org/bugzilla/show_bug.cgi?id=21581). So don't be too worried about it.


ajaykuma...@gmail.com

unread,
Jan 14, 2015, 1:12:47 PM1/14/15
to std-dis...@isocpp.org
Hello sir, I have made ashort note on this namespace topic with  examples that may give u clarity abt these things. I hope it will be helpful for u..

http://comsciguide.blogspot.in/2014/12/namespace_26.html

ajay kumar

unread,
Sep 24, 2015, 11:37:43 AM9/24/15
to ISO C++ Standard - Discussion

Andrey Semashev

unread,
Sep 24, 2015, 12:17:59 PM9/24/15
to std-dis...@isocpp.org
On Thu, Sep 24, 2015 at 6:37 PM, ajay kumar <ajaykuma...@gmail.com> wrote:
> http://comsciguide.blogspot.com/
>
> On Monday, February 4, 2013 at 3:21:02 PM UTC+5:30, Klaim - Joël Lamotte
> wrote:
>>
>> Hi, I think I need some clarification on the intended behavior of
>> anonymous namespace.
>>
>> First, can someone confirm me that an object in an anonymous namespace in
>> a unique cpp is equivalent to defining it static? Or should I add always
>> static anyway?

No, it's not equivalent.

Static variables and functions have internal linkage, which basically
means they are local to a single TU. If a variable has internal
linkage and declared in a header which is included in two TUs, each TU
receives a local copy of the variable. As far as language concerns,
local variables/functions are not visible to foreign TUs (i.e. do not
participate in symbol linking).

Anonymous namespace is effectively a namespace with a name that is
unique across all TUs of the program. So if you declare an anonymous
namespace in a header and include it in two TUs you effectively have
two distinct namespaces (with two copies of the namespace contents,
obviously). Note that these copies have different names.

Unlike static variables, anonymous namespaces do not affect linkage.
This means that you can have variables and functions with external
linkage in anonymous namespaces, which lets you use their addresses as
template arguments.

>> Second, I just tried to write a constant in an anonymous namespace, but
>> defined in a header.
>> I first thought that I would have a multiple symbol definition error on
>> link but both GCC4.7 and VS2012 seem to compile and link it fine (the code:
>> https://compilr.com/klaim/test-anonymous-namespace/).
>> My guess is that the object is redefined in each cpp using it.
>> Is it supposed to be allowed by the standard or is it undefined behaviour?

const-qualified variables have internal linkage by default. This means
that, unless the compiler is able to optimize it away, each TU
receives a copy of that variable. You have to declare the variable
with 'extern' to give it external linkage. After that you'll have to
define that variable in one TU to give it storage.

Myriachan

unread,
Sep 24, 2015, 2:42:19 PM9/24/15
to ISO C++ Standard - Discussion
On Thursday, September 24, 2015 at 9:17:59 AM UTC-7, Andrey Semashev wrote:
Unlike static variables, anonymous namespaces do not affect linkage.
This means that you can have variables and functions with external
linkage in anonymous namespaces, which lets you use their addresses as
template arguments.


That's incorrect.  [basic.link]/4:

An unnamed namespace or a namespace declared directly or indirectly within an unnamed namespace has
internal linkage. All other namespaces have external linkage. A name having namespace scope that has not
been given internal linkage above has the same linkage as the enclosing namespace if it is the name of:
...variable, function, named class, etc...

Melissa

Jens Maurer

unread,
Sep 24, 2015, 3:54:45 PM9/24/15
to std-dis...@isocpp.org
On 09/24/2015 06:17 PM, Andrey Semashev wrote:
> This means that you can have variables and functions with external
> linkage in anonymous namespaces, which lets you use their addresses as
> template arguments.

There has been quite a bit of change in this area lately.

In particular, there is no longer a requirement that template
arguments have external linkage; see 14.3.2.

Jens

Andrey Semashev

unread,
Sep 24, 2015, 4:10:35 PM9/24/15
to std-dis...@isocpp.org
Hmm, I guess, I'm remembering things as they were in the C++03 days.

BTW, gcc 4.9 allows to use an address of a function in an anonymous
namespace in template parameters, both in C++03 and C++11 mode. It fails
C++03 mode if the function is static.

ajay kumar

unread,
Oct 4, 2015, 7:17:23 AM10/4/15
to ISO C++ Standard - Discussion


On Monday, February 4, 2013 at 3:21:02 PM UTC+5:30, Klaim - Joël Lamotte wrote:
Reply all
Reply to author
Forward
0 new messages