Bug 18267 - external linkage of functions declared in an anonymous namespace
Summary: external linkage of functions declared in an anonymous namespace
Status: RESOLVED INVALID
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 3.4.2
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2004-11-01 18:30 UTC by Benoît Dejean
Modified: 2005-07-23 22:49 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Benoît Dejean 2004-11-01 18:30:14 UTC
Here are 3 functions and a dummy main:

--begin--
int one() { return 1; }

static int two() { return 2; }

namespace
{
  int three() { return 3; }
}

int main()
{
  return one() + two() + three();
}
--end--

i was expecting that g++ handled two() and three() the same way, that
is to say generated object-code with internal linkage.
 
But g++ doesn't. three() has external linkage, just like one(). TCPPPL
says that an anonymous namespace is a namespace with a unique
name. Fine. Then why g++ does not optimize this ?  The previous
program returns 6. g++ outputs a definition for three(), but it is
obvious that two() and three() definitions are no longer needed
because they've been inlined. That's why g++ doesn't output a
definition for two(). In the end, i get a never-used definition of
three() ...

Thanks

>>> LC_ALL=C g++-3.4 -v
Reading specs from /usr/lib/gcc/powerpc-linux/3.4.2/specs
Configured with: ../src/configure -v
--enable-languages=c,c++,java,f77,pascal,objc,ada --prefix=/usr
--libexecdir=/usr/lib --with-gxx-include-dir=/usr/include/c++/3.4
--enable-shared --with-system-zlib --enable-nls --without-included-gettext
--program-suffix=-3.4 --enable-__cxa_atexit --enable-libstdcxx-allocator=mt
--enable-clocale=gnu --enable-libstdcxx-debug --enable-java-gc=boehm
--enable-java-awt=gtk --disable-multilib --disable-multilib powerpc-linux
Thread model: posix
gcc version 3.4.2 (Debian 3.4.2-3)
Comment 1 Andrew Pinski 2004-11-01 19:05:54 UTC
The main reason IIRC for this is because C++ and export templates (even though we don't implement 
export yet).
Comment 2 Giovanni Bajo 2004-11-01 23:52:19 UTC
Names declared in anonymous namespaces do not get internal linkage by default. 
In fact, they can be used as template non-type arguments (names with internal 
linkage cannot be used in such contexts).
Comment 3 Benoît Dejean 2004-11-02 00:10:48 UTC
of course. but if they are not ? they should be optimize, no ?
if g++ inlines three(), why does it remove three() global definition if it's
never used ?
Comment 4 Giovanni Bajo 2004-11-02 00:19:56 UTC
GCC is not allowed to remove the definition of a function with external 
linkage. The fact that nobody will be able to call it because it is in an 
anonymous namespace it is irrelevant.
Comment 5 Benoît Dejean 2004-11-02 00:48:13 UTC
i understand your point of view though i'm not happy with g++ behaviour. A
function with external linkage that can't be called seems like an oxymoron to
me. This makes my library very big. i had to mark a lot of functions inline to
get the behaviour i expect. But it is hard to manage. I have lo live with it.

Thanks for your explanation.
Comment 6 Giovanni Bajo 2004-11-02 01:22:39 UTC
It is not exactly a G++ choice. This is what the ISO/ANSI C++ International 
Standard mandates. I suggest you to post a mail to the newsgroup 
comp.lang.c++.moderated or to comp.std.c++ to enquire an explanation for the 
rationale.

Also, notice you can try compiling your code with -ffunction-sections to let 
the linker drop the unused functions from the final executable. But remember 
that this option might regress the code performance a bit on x86 because it 
forces the compiler to generate slower code for each function call.

Alternatively, why don't you simply use "static"?
Comment 7 Wolfgang Bangerth 2004-11-02 01:53:14 UTC
This point has been discussed in a number of PRs already. I maintain 
my position that gcc could invoke the as-if rule to give these functions 
internal linkage if they aren't taken as template parameters. Since 
there is no user-visible effect, this is well within the allowed range, 
and it would save us from a good number of the problems we've had over 
time with mangling of symbol names in anonymous namespaces. 
 
W. 
Comment 8 Benoît Dejean 2004-11-02 09:21:23 UTC
>> Alternatively, why don't you simply use "static"?

because everybody tells me that 'static' is deprecated in favor of 'namespace{}'

>> gcc could invoke the as-if rule to give these functions internal linkage

this sounds great.
Comment 9 Giovanni Bajo 2004-11-02 11:55:17 UTC
(In reply to comment #7)

> This point has been discussed in a number of PRs already. I maintain 
> my position that gcc could invoke the as-if rule to give these functions 
> internal linkage if they aren't taken as template parameters. Since 
> there is no user-visible effect, this is well within the allowed range, 
> and it would save us from a good number of the problems we've had over 
> time with mangling of symbol names in anonymous namespaces. 

I don't think it would solve the problem about mangling because the 
function/classes in anonymous namespaces can still be used as template 
arguments, so they could end up being mangled.

But it is an interesting point of view.
Comment 10 Wolfgang Bangerth 2004-11-02 16:10:47 UTC
I don't want to have these symbols not mangled (they need indeed be 
mangled and randomized), the problem is that the randomness is sometimes 
not enough. See PR 9393 for a case that would have been solved with 
making symbols have internal linkage. 
 
W.