ASPN ActiveState Programmer Network
ActiveState
/ Home / Perl / PHP / Python / Tcl / XSLT /
/ Safari / My ASPN /
Cookbooks | Documentation | Mailing Lists | Modules | News Feeds | Products | User Groups


Recent Messages
List Archives
About the List
List Leaders
Subscription Options

View Subscriptions
Help

View by Topic
ActiveState
.NET Framework
Open Source
Perl
PHP
Python
Tcl
Web Services
XML & XSLT

View by Category
Database
General
SOAP
System Administration
Tools
User Interfaces
Web Programming
XML Programming


MyASPN >> Mail Archive >> boost
boost
RE: [boost] boost bind/functional/reference wrapper/mem_fn
by Fernando Cacciola other posts by this author
Jan 30 2002 7:19PM messages near this date
RE: [boost] boost bind/functional/reference wrapper/mem_fn | Help - python doesn't see my init method.
----- Original Message -----
From: Yitzhak Sapir <ysapir@[...]..> 
To: <boost@[...].com> 
Sent: Wednesday, January 30, 2002 11:39 AM
Subject: RE: [boost] boost bind/functional/reference wrapper/mem_fn


>  [...]
>  namespace
>  {
>  inline boost::_bi::arg<1> _1() { return boost::_bi::arg<1>(); };
>  inline boost::_bi::arg<2> _2() { return boost::_bi::arg<2>(); };
>  inline boost::_bi::arg<3> _3() { return boost::_bi::arg<3>(); };
>  inline boost::_bi::arg<4> _4() { return boost::_bi::arg<4>(); };
>  inline boost::_bi::arg<5> _5() { return boost::_bi::arg<5>(); };
>  inline boost::_bi::arg<6> _6() { return boost::_bi::arg<6>(); };
>  inline boost::_bi::arg<7> _7() { return boost::_bi::arg<7>(); };
>  inline boost::_bi::arg<8> _8() { return boost::_bi::arg<8>(); };
>  inline boost::_bi::arg<9> _9() { return boost::_bi::arg<9>(); };
>  }
> 
>  This way it can remain one header with no extra defines based on whether
>  you want/don't want precompiled headers. Or is something wrong with
>  this code?
> 
Jus a note: The definitions of the inline functions _X() are inside an
unnamed namespace.

Unless I'm missing something, it is required that inline functions be
declared inside an unnamed namespace.
Just for the records, I'll explain this issue in some detail:


Using C terminology, a header might need to declare objects at file scope ,
traditionally called static objects.
'static' objects have internal linkage , meaning that their names can be
seen from other scopes, but each translation unit (TU) will have its own
distinct definition of these objects.

A library could require visible objects (i.e., bind requires _X). If those
objects are declared without external linkage, the linker will encounter
duplicate symbols because different TUs will have the same definition.
Usually, if the objects are not meant to be 'shared' across different TUs,
libraries declare those objects with internal linkage. Each TU that includes
their declarations receives a distinct copy (with a distinct symbol), thus
there are no duplicate symbols seen by the linker.

In C, this is accomplished using the 'static' specifier.

In C++, an object [first] declared with 'static' or 'const' has internal
linkage.
(* in C, however, 'const' doesn't specify any linkage).

However, in C++, the usage of 'static' for file scope declarations is
deprecated in favor of a technique which has a similar effect.

Both in C and C++, objects with external linkage share the same
definition (and symbol) across translation units. Therefore, these objects
are required to have the same address in all TUs, so the linker can collapse
all initially separated definitions into a single one.

A variable declared with namespace scope, such as:

namespace boost {

boost::_bi::arg<1>  _1;
}

has external linkage by default. It means that '_1' will be the same object
in every TU.

An unnamed namespace introduces a nested namespace with a hidden name,
along with an implicit using directive that allows this hidden name to be
implicit in the object id.

Therefore, if '_1' appears inside an unnamed namespace:

namespace boost {
namespace {
boost::_bi::arg<1>  _1;
}
}

its fully qualified-id (name) is actually something like:

boost::unique_to_the_current_TU::_1.

But since the hidden namespace unique_to_the_current_TU is brought to
namespace 'boost' with an implicit using directive, you don't have to type
it and can refer to it simply as boost::_1

However, the object has whatever linkage it is given, and in this case it is
external linkage since it isn't static nor const.

Having external linkage means that boost::_1 is totally visible from every
TU, but, since its name incorporates the hidden namespace which is specific
to each TU, there are no duplicate symbols seen by the linker.

IOW, we put object declarations/definitions inside an unnamed namespace in
order to avoid duplicate symbols across TUs, emulating the effect of
internal linkage, and when we can't give the objects external linkage
because that would require an additional source file to be supplied.

non-inline functions have external linkage by default, thus they require a
single definition in a single source file. Conversely, inline functions have
internal linkage by default, so they don't require a separate source file.

As a conclusion, we don't need to put inline functions in an unnamed
namespace because they have internal linkage
(unless of course there is something I misunderstand or not seeing...)


Fernando Cacciola
Sierra s.r.l.
 fcacciola@[...]..
www.gosierra.com
Thread:
Yitzhak Sapir
Peter Dimov
Fernando Cacciola
Fernando Cacciola

Privacy Policy | Email Opt-out | Feedback | Syndication
© ActiveState Software Inc. All rights reserved