This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Anonymous Namespaces


Chris Lattner <sabre@nondot.org> writes:

| On 31 Jan 2004, Gabriel Dos Reis wrote:
| > | With the LLVM G++ front-end, all entities declared in an anonymous
| > | namespace are emitted with internal linkage, including any related RTTI
| > | info, vtables, etc.
| >
| > Do you implement the rest of the C++ language (e.g. proper two-phase
| > name lookup)? (Note that exported templates also interact with names
| > with internal linkage, but granted, we don't have export yet).
| 
| Yes, we use the GCC "3.4" parser, so if it does, we do.  We also don't
| support export yet.  Regardless, if export was implemented, and an entity
| was not involved with an exported template, it should still be marked as
| internal.

You can't have that information availabale at parsing time.  You'd
need to postpone the tramsutation to link time.  The reason is that,
the instantiation of exported template can trigger  instantiation in
chains and those usually implies name lookup  -- which will happen at
sort of "link time"  when the different translation units are being
combined together.  The second phase of name critically needs to know
whether a function has internal linkage or not (see below).  If you
mark a function defined in an unnamed namespace as having internal
linkage before the second phase of name lookup, you'll obvious produce
wrong code. 

| > As I explained in another message, if the issue is this particular
| > optimization, the right thing to do is teach the programmed inliner
| > about unnamed namespace instead of fiddling with the semantics.
| 
| It's not just the inliner, it's also the global dead code elimination
| stuff, and a variety of other optimizations.  For example, the LLVM dead
| argument eliminator and IP constant prop passes are able to do a lot of
| nice things to code, but only if it is marked with internal linkage.

But what you need is not "internal linkage" (i.e. declaring  the
functions or objects as "static"), but the notion of "regarless of the
actual linkage of this entity, it is referenced only in this
translation unit and cannot appear somewhere else".

| Also, adding gigantic random prefixes to program objects amounts to
| obfuscation, and have their own problems.
| 
| > And if "static" is what you want; just use "static" :-)
| 
| No.  Static is officially deprecated for that use in C++, not to mention
| really ugly. 

No, no. Read the C++ standard text carefully to see how the
deprecation text is worded.  But, even then, it has been found that
that "deprecation" is hasty and in effect menaingless.  It is very
simple: If you mean static, then use static.  It just can't go away.

For those who followed the discussion about export and the paper by
Herb and Tom, one of the issue was that some programmers have been
confusing "being declared in unnamed namespace" with "being declared
static".  Those people have been "surprised" to see that their
functions they put in an unamed namespace have been reached across
translation units and causing ambiguity.  Presumably, they have been
misinformed and misguided. 

The relevant section is

14.6.4.2/1

   For a function call that depends on a template parameter, if the
   function name is an unqualifiedid but not a templateid, the
   candidate functions are found using the usual lookup rules (3.4.1, 
   3.4.2) except that:
   -- For the part of the lookup using unqualified name lookup
      (3.4.1), only function declarations with external linkage from
      the template definition context are found. 

   -- For the part of the lookup using associated namespaces (3.4.2),
      only function declarations with external linkage found in either
      the template definition context or the template instantiation
      context are found. 

So, it would really want to have "control" over your function name, and
static is what you want, declare it static, unless you do intend to
allow it espace that translation unit.  "Unnamed namespace" is not a
shortcut for "static".  Period.

I strongly advise against a naive approach to this issue, that would
not have an understanding of unnamed namespace semantics, C++ name
lookup rules and exported templates.

| Also, you can't mark a class 'static' (making the member
| functions, vtables, rtti info, etc all internal).

So what?  What you want is not "static" but a way to say "this thing
is used only in this translation unit".

| > | This has absolutely no effect on the front-end, we handle it in our
| > | version of "expand".
| >
| > Hmm, are we talking about the C++ front-end?  Notice that anything I
| > said about has to do with the C++ front-end, not with the middle-end
| > or the back-end.
| 
| That's fine, I just told you how we _implemented it_.

And I just asked you if you implemented the rest of the language.
Because what it important is not what you implement in isolation, but
the interaction with the rest of the language.  I just explained you
how it leads to incorrect translation of conforming codes.

-- Gaby


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]