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
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.
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.
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:
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.
>> 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.