This is the mail archive of the
gcc-help@gcc.gnu.org
mailing list for the GCC project.
Re: Weak symbols and inline
- From: Marc Glisse <marc dot glisse at inria dot fr>
- To: Paul Smith <paul at mad-scientist dot net>
- Cc: Jonathan Wakely <jwakely dot gcc at gmail dot com>, gcc-help <gcc-help at gcc dot gnu dot org>
- Date: Fri, 28 Feb 2014 22:15:28 +0100 (CET)
- Subject: Re: Weak symbols and inline
- Authentication-results: sourceware.org; auth=none
- References: <1393527190 dot 2823 dot 515 dot camel at pdsdesk> <alpine dot DEB dot 2 dot 10 dot 1402272019340 dot 3594 at laptop-mg dot saclay dot inria dot fr> <1393529487 dot 2823 dot 520 dot camel at pdsdesk> <CAH6eHdRuG3KuhBFeFtbxt9G7SoQ84yS7mvR+OdpXQs6CyjQRLw at mail dot gmail dot com> <1393620036 dot 2823 dot 571 dot camel at pdsdesk>
- Reply-to: gcc-help at gcc dot gnu dot org
On Fri, 28 Feb 2014, Paul Smith wrote:
Can I move out of the clouds of standards-compliance and into the mud of
implementations? :-). Speaking specifically about GCC/binutils on
GNU/Linux, although at some point I'll need to address Windows MSVC and
MacOSX Clang/LLVM as well (not here, although I welcome pointers).
I'm creating a shared library from a large existing C++ codebase. The
interface to the shared library is well-designed using abstract classes
and factories, and correct handling of memory.
In my shared library I want to use an alternate memory manager, and so I
want to override global operator new/delete.
However, I don't want my memory manager to "leak out" into the
executable using the shared library; I want the executable (also written
in C++) to be able to define its own memory management (or get the
system new/delete by default) without impacting my library and vice
versa.
I build all my code with -fvisibility=hidden, then mark the factory
functions as __attribute__((visibility("default"))). Of course I didn't
mark the global operator new/delete as "default".
However, even though I didn't mark them that way, running nm on the .so
shows them as public symbols ("T"). I'm assuming that these functions
are handled specially so that the visibility=hidden default doesn't
apply to them? I get a compiler error if I try to force them with
__attribute__.
So then I tried to use inline versions of global new/delete. If I
further add __attribute__((force_inline)) then it APPEARS to do what I'd
like: none of my objects are exporting global new/delete.
Header <new> contains:
#pragma GCC visibility push(default)
__attribute__((__externally_visible__));
It seems hard to counter those effects.
Of course this is a bit hackish, and more concerning it means that if I
forget to include the header with the inline definitions into any of my
translation units then I silently get the wrong ones.
Is there a better supported, more "approved" way to handle this
requirement?
I haven't looked at it closely, but maybe asking the linker directly
(instead of telling gcc to tell the linker), for instance through a map
file, could help?
The simplest is probably to use asm("other_name_for_new") on a declaration
of new, so it is still visible but with a different name...
Would the standard-conforming answer be modifying all classes to declare
their own new/delete instead of relying on global new/delete, maybe by
introducing a common base class for everything? That's just not
feasible for me at the moment: there are thousands of classes,
templates, etc. etc. I need something less invasive.
--
Marc Glisse