Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

warning: ... has a field ... whose type uses the anonymous namespace

1,504 views
Skip to first unread message

Helmut Jarausch

unread,
Nov 20, 2008, 3:37:35 PM11/20/08
to
Hi,

can anybody please explain the following warning to me

../include/zthread/PoolExecutor.h:58: warning:
'ZThread::PoolExecutor' has a field 'ZThread::PoolExecutor::_impl' whose
type uses the anonymous namespace

Many thanks for a hint,

Helmut Jarausch

Lehrstuhl fuer Numerische Mathematik
RWTH - Aachen University
D 52056 Aachen, Germany

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Jyoti Sharma

unread,
Nov 21, 2008, 7:52:30 AM11/21/08
to
On Fri, 21 Nov 2008 02:07:35 +0530, Helmut Jarausch <jara...@skynet.be>
wrote:

> can anybody please explain the following warning to me
>
> ../include/zthread/PoolExecutor.h:58: warning:
> 'ZThread::PoolExecutor' has a field 'ZThread::PoolExecutor::_impl' whose
> type uses the anonymous namespace
>

1. A namespace with no identifier before an opening brace produces an
unnamed namespace. Each translation unit may contain its own unique
unnamed namespace.

2. Items defined in an unnamed namespace have internal linkage.

What you have got is a *warning*, and the above two points may help
explaining why the compiler issued such a warning.

regards,
Jyoti

Martin Vuille

unread,
Nov 21, 2008, 2:50:17 PM11/21/08
to
"Jyoti Sharma" <jyoti....@gmail.com> wrote in
news:op.ukx6jwbotp94fi@jyoti:

>
> 2. Items defined in an unnamed namespace have internal linkage.
>

Is that true? Where is it guaranteed by the standard? This has
not been my experience.

MV

--
I do not want replies; please follow-up to the group.

Chris Uzdavinis

unread,
Nov 21, 2008, 2:59:32 PM11/21/08
to
On Nov 20, 3:37 pm, Helmut Jarausch <jarau...@skynet.be> wrote:
> Hi,
>
> can anybody please explain the following warning to me
>
> ../include/zthread/PoolExecutor.h:58: warning:
> 'ZThread::PoolExecutor' has a field 'ZThread::PoolExecutor::_impl'
whose
> type uses the anonymous namespace

Each .cpp file you compile into your project ("translation unit") has
its own unique anonymous namespace. It's a misnomer to say "the"
anonymous namespace because that implies there is only one.

Thus, declaring types in an anonymous namespace in a header has the
subtle effect of putting that type in a different namespace for every
translation unit that includes your header.

Perhaps it's easier to describe the problem with an example:

// common.hpp
#ifndef COMMON_HPP
#define COMMON_HPP
namespace {
class Impl { };
} // anonymous

class X {
Impl data;
};
#endif // COMMON_HPP


// file1.cpp
#include "common.hpp"

void f() {
X object;
}


// file2.cpp
#include "common.hpp"

void g() {
X object;
}


When we compile file1, common.hpp declares (anon)::Impl in file1's
anonymous namespace, and so class X is something like this under the
hood:

namespace file1_anon_ns {
class Impl { };
}

// inside file1
class X {
file1_anon_ns::Impl data;
};

But when we're compiling file2, we also include common, which puts
(anon)::Impl in file2's anonymous namespace, something like this:

namespace file2_anon_ns {
class Impl { };
}

// inside file2
class X {
file2_anon_ns::Impl data;
};


Now the problem should be clear: the definition of X is not the same
in different translation units, violating the One Definition Rule.

--
Chris

Daniel Krügler

unread,
Nov 21, 2008, 2:50:27 PM11/21/08
to
On 21 Nov., 13:52, "Jyoti Sharma" <jyoti.mic...@gmail.com> wrote:
> On Fri, 21 Nov 2008 02:07:35 +0530, Helmut Jarausch <jarau...@skynet.be>

> wrote:
> > can anybody please explain the following warning to me
>
> > ../include/zthread/PoolExecutor.h:58: warning:
> > 'ZThread::PoolExecutor' has a field 'ZThread::PoolExecutor::_impl'
whose
> > type uses the anonymous namespace
>
> 1. A namespace with no identifier before an opening brace produces an
> unnamed namespace. Each translation unit may contain its own unique
> unnamed namespace.

Right.

> 2. Items defined in an unnamed namespace have internal linkage.

Wrong, they have normal external linkage until they are declared
otherwise (i.e. with the static qualifier). But this has a similar
effect like internal linkage. Unnamed namespace entities are
not available in different TU (translation units), because they
cannot be named outside, due to their unique, but *unknown*
name (for the programmer). Therefore explicit static linkage
specification via the static keyword is deprecated as of
[namespace.unnamed]/2:

"The use of the static keyword is deprecated when declaring
objects in a namespace scope (see annex D); the unnamed-
namespace provides a superior alternative."

In other words: Regarding linkage rules an unnamed namespace
does not behave differently as named namespace.

*Usually* an unnamed namespace in a (shared) header file
should be avoided, because the seemingly same entity declared
there will be actually different enties for each TU which includes
this header. But in this regard this is quite similar to an entity
declared with internal linkage in a shared header.

Greetings from Bremen,

Daniel Krügler

Joe Smith

unread,
Nov 21, 2008, 6:59:01 PM11/21/08
to

"Martin Vuille" <clcppm...@this.is.invalid> wrote in message
news:Xns9B5D54682E0...@127.0.0.1...

> "Jyoti Sharma" <jyoti....@gmail.com> wrote in
> news:op.ukx6jwbotp94fi@jyoti:
>
>>
>> 2. Items defined in an unnamed namespace have internal linkage.
>>
>
> Is that true? Where is it guaranteed by the standard? This has
> not been my experience.
>
No C++03's footnote 83 is clear on this:
Although entities in an unnamed namespace might have external linkage, they
are
effectively qualified by a name unique to their translation unit and
therefore
can never be seen from any other translation unit.

The problem here though is that it will be unusuable in other translation
units, as only a forward declaration could be made for
ZThread::PoolExecutor.
If one were to include a full class definition in a different translation
unit, the two definitions would not be equivelent since the _impl member
would have a different type in each. This results in undefined behavior
as per [basic.def.odr]/5.


--

Francis Glassborow

unread,
Nov 21, 2008, 6:54:31 PM11/21/08
to
Martin Vuille wrote:
> "Jyoti Sharma" <jyoti....@gmail.com> wrote in
> news:op.ukx6jwbotp94fi@jyoti:
>
>> 2. Items defined in an unnamed namespace have internal linkage.
>>
>
> Is that true? Where is it guaranteed by the standard? This has
> not been my experience.
>
> MV
>

IIRC it is false. Names declared in an unnamed namespace have external
linkage but their fully qualified name is unutterable.

--

0 new messages