Members of anonymous namespaces are very much like static variables/functions, except that they are given external linkage but a name that is mangled in a way so as to make them unique. This is not the case if it happens in a header file that is then precompiled, subsequently leading to linker errors due to duplicate symbols. Example: echo 'namespace { int i; }' > x.h echo '#include "x.h"' > a.cc echo '#include "x.h"' > b.cc echo 'int main () {}' >> b.cc /home/bangerth/bin/gcc-3.4-pre/bin/c++ -c x.h /home/bangerth/bin/gcc-3.4-pre/bin/c++ -c a.cc /home/bangerth/bin/gcc-3.4-pre/bin/c++ -c b.cc /home/bangerth/bin/gcc-3.4-pre/bin/c++ a.o b.o b.o(.bss+0x0): multiple definition of `(anonymous namespace)::i' a.o(.bss+0x0): first defined here collect2: ld returned 1 exit status The reason is the mangled name this variable is given: g/x> nm a.o 00000000 B _ZN20_GLOBAL__N_x.huNZudc1iE g/x> nm b.o 00000000 B _ZN20_GLOBAL__N_x.huNZudc1iE 00000000 T main The standard says that they must be unique every time, but obviously they are not. This situation is a little unfortunate, since for example boost uses such variables in anonymous namespaces in some headers, meaning that one cannot use precompiled headers in conjunction with boost. W. Release: unknown Environment: present mainline (3.4)
Responsible-Changed-From-To: unassigned->geoffk Responsible-Changed-Why: Master of pch and author of a very much related patch for non-pch quite recently -- what a lucky coincidence :-)
What we want to do with this is to stop giving anonymous namespace members globally-visible names, and then we don't need to make their names unique.
Subject: Re: Members of anonymous namespaces get name mangled with header name > What we want to do with this is to stop giving anonymous > namespace members globally-visible names, and then we don't need to make > their names unique. Yes, except for the open question of how this would interfere with "export". Not that I care about this at the moment, but should be considered before a fix. On the other hand, I care very much about this particular PR, since one cannot use PCH with BOOST at present :-( I am mostly neutral whether this is fixed by munging names of giving them internal linkage, as long as it's being fixed... W. ------------------------------------------------------------------------- Wolfgang Bangerth email: bangerth@ices.utexas.edu www: http://www.ices.utexas.edu/~bangerth/
Subject: Re: Members of anonymous namespaces get name mangled with header name > From: Wolfgang Bangerth <bangerth@ices.utexas.edu> > Date: Fri, 20 Jun 2003 16:37:39 -0500 > > What we want to do with this is to stop giving anonymous > > namespace members globally-visible names, and then we don't need to make > > their names unique. > > Yes, except for the open question of how this would interfere with "export". > Not that I care about this at the moment, but should be considered before a > fix. I don't see how it could possibly interfere with the current export non-implementation. If export gets implemented in future, it'll require some way to communicate information between translation units, and while it's doing that it can also ensure that names are unique (which will surely be one of the smallest problems that need to be solved).
Subject: Re: Members of anonymous namespaces get name mangled with header name > I don't see how it could possibly interfere with the current export > non-implementation. If export gets implemented in future, it'll > require some way to communicate information between translation units, > and while it's doing that it can also ensure that names are unique > (which will surely be one of the smallest problems that need to be > solved). I totally agree. I don't see a problem there either. That was just one of the reasons I heard a while back when this topic was brought up before. (No, don't ask me when and where this was.) I'd favor going the way with internal linkage now, and think about the interaction with export when that is imminent. AFAIK, nobody ever even uttered he'd be interested in implementing export... W. ------------------------------------------------------------------------- Wolfgang Bangerth email: bangerth@ices.utexas.edu www: http://www.ices.utexas.edu/~bangerth/
A similar issue was brought up in the thread "Anonymous Namespaces" found here http://gcc.gnu.org/ml/gcc/2004-01/msg02323.html and http://gcc.gnu.org/ml/gcc/2004-02/msg00001.html . The new unit-at-a-time optimizer is unable to optimize functions inside anonymous namespaces namespace becuase they technically have external linkage. The solution seams to be "to make the C++ front end not use (TREE_PUBLIC(x) == false) to mean a symbol with internal linkage. Instead, a language-specific decl flag ought to be allocated to mean exactly 'internal linkage', and all local symbols ought to get TREE_PUBLIC false." according to Zack Weinberg. I hope this will get fixed in time for Gcc 3.4. I know nothing of Gcc internals so I can't do it myself so I am hoping someone else will.
Are there any plans to fix this for 3.5. f.ex.?
*** Bug 21179 has been marked as a duplicate of this bug. ***
Three months later, any movement on this bug? How is the PCH code in the 4.0 branch? PCH support would be a godsend to people supporting large C++ projects on GCC.
Subject: Re: Members of anonymous namespaces should be 'static' On 31/07/2005, at 7:24 PM, cpence at gmail dot com wrote: > Three months later, any movement on this bug? How is the PCH code > in the 4.0 > branch? PCH support would be a godsend to people supporting large C > ++ projects > on GCC. There aren't any particular plans I know of to work on this bug, although I'd be happy to hear of some. As far as I know PCH works fine in the 4.0 branch (but this bug isn't fixed).
Although members of anonymous namespaces can be made 'static' on every target, they can all be given the same name on targets with weak symbol support, since on other targets the typeinfo is compared by name so different types must be given different names.
See: http://gcc.gnu.org/ml/gcc-patches/2005-09/msg00772.html This is a great idea. It would allow anonymous namespaces to be useful, and more designs (at least g++ designs) could use them. -benjamin
*** Bug 25915 has been marked as a duplicate of this bug. ***
This is the same original report as bug 25915, which then was generalised as follows: Any entity which could be defined more than once (like a class or an inline function) but whose token stream refers to a function or variable which is not TREE_PUBLIC, actually can't be defined more than once, and so every part of such entity can be made not-TREE_PUBLIC. Exception: if the object referred to is 'const', is of scalar type, is initialized with a constant expression, and the value but not the address of the object is used, it doesn't count. For additional details, including additional cases where this applies and an explanation of how it applies to templates, see [basic.def.odr] paragraph 5.
Another case is when someone writes struct a_struct __attribute__((visibility(hidden))); void foo(a_struct &) { } Even though "foo" is not marked hidden it should still be hidden, because it could be overloaded in a different shared object with a parameter which has type 'a_struct &' but is a different type. This is especially important when 'func' is 'operator ==' or similar.
Oops! I got confused about visibility vs. TREE_PUBLIC. I think it would be better to track the visibility stuff under a different bug. The previous comment does apply when something is in an anonymous namespace, but it's only an optimisation, not required for correctness, since at the moment we give things in an anonymous namespace a random name to avoid exactly this kind of problem.
I made 26612 to track the similar situation with visibility.
I think the summary is misleading; the change requested is an optimization. The testcase breaks because PCH breaks anonymous namespace naming so that it gets the same name in all translation units. I assume that the same problem happens with other users of get_file_function_name.
@#18: I disagree. This bug is the only thing preventing anonymous namespaces from working together with PCH. As such, it's a bug, insofar as it keeps a _very_ worthwhile feature (namely, precompiling massive C++ headers like Boost) from working.
Subject: Re: use ODR rules to make C++ objects not be TREE_PUBLIC Sorry I wasn't clear; I agree that this is an important bug. I meant that fixing the unique anonymous namespace name in the presence of PCH is the right way to fix it. Jason
*** Bug 26895 has been marked as a duplicate of this bug. ***
The PCH problem with get_file_function_name is independent of the question of giving anonymous namespace members internal linkage. We still need to give them distinct names; we are giving up on address comparison of type_infos because of problems with plugins.
(In reply to comment #22) > The PCH problem with get_file_function_name is independent of the question of > giving anonymous namespace members internal linkage. We still need to give > them distinct names; we are giving up on address comparison of type_infos > because of problems with plugins. If you're giving up address comparison on type_info, you still have to find a way where two typeinfo objects with the same C++ name can be different, due to this example: A shared object contains class A { }; class B __attribute__((visibility("hidden"))) : class A { }; void f () { throw new B(); } A main program contains: class A { }; extern void f(); class B __attribute__((visibility("hidden"))) { int x; }; // not an A int main() { try { f(); } catch (B * p) { abort(); } catch (A * p) { exit (0); } abort(); } This program should not abort, because the 'B' in the main program is not the same as the 'B' in the dylib. My suggestion would be to include &__dso_handle in the typeinfo for objects with hidden visibility, and also compare that. Now, if you're doing this for visibility, you can also do it for anonymous namespaces. Just find any address in the translation unit that contains the anonymous namespace (hey, how about the address of the typeinfo itself?), and consistently include that address in the typeinfo, and compare that.
Did my recent visibility patch fix this?
Fixed for 4.2.0.
*** Bug 29085 has been marked as a duplicate of this bug. ***
Would it be possible to backport this fix to the 4.1 tree? It would prove very, very useful.
*** Bug 34309 has been marked as a duplicate of this bug. ***