Placement of vtables, inlines and such
Jim Dehnert
dehnert at baalbek.engr.sgi.com
Tue Jun 29 20:22:02 UTC 1999
Thanks for the explanations, Christophe.
> From: Christophe de Dinechin <ddd at cup.hp.com>
>
> Now, the COMDAT issue is as follows: a COMDAT section is, in some
> cases, slightly more difficult to handle (at least, that's the
> impression Jason gave me). For statics with runtime initialization,
> what you can do is reserve COMMON space ('easier'), then initialize
> that space at runtime. As I said, the problem is if two compilers
> disagree on whether this is a runtime or a compile time
> initialization, such as in :
>
> inline int f() { return 1; }
> int x = f(); // Static (COMDAT) or
> Dynamic (COMMON) initialization?
>
> So I personally recommend that we put everything in COMDAT.
I may be slow, but I think I'm finally understanding :-).
I was looking for too much. I gather now that the "COMMON" solution
isn't really a different solution, it's just the observation that, if
there is no static initialization, COMMON serves the same purpose as
COMDAT. Correct? In that case, as Christophe proposes, COMDAT by
itself is clearly adequate (and COMMON by itself is not, unless we
require dynamic initialization, which seems objectionable).
Given a COMDAT-based ABI, for objects without any static initialization,
one could emit a COMMON symbol instead or an "empty" COMDAT, and either
would be suitable. There are a couple of reasons one might prefer
COMMON:
- If there are enough with only dynamic (or no) initialization to be
of concern, a COMMON symbol is much lighter-weight in the object
than a section, especially if the object is large.
- If one were concerned about different compilers making different
initialization decisions (e.g. due to inlining), one would
presumably define the COMMON symbol as being preempted by the
COMDAT symbol (which I envision as just a normal GLOBAL symbol with
a flag).
The second point touches on Christophe's earlier concern about
compilers and inlining. It will partially solve the problem -- given
objects from one compiler which does all the initialization
dynamically, and another which does some or all of it statically, the
COMDAT from the latter will preempt the COMMON from the former, and
whichever dynamic initializer is actually chosen will work.
However, if both compilers initialize some of the data statically, but
not the same part, they will both produce COMDAT sections, but
different ones, and it becomes important that the initializer chosen
match the COMDAT instance chosen. One solution would be to associate
the initializer with the COMDAT. Another would be to mark which parts
of the COMDAT contain valid initialization and have the linker merge
the non-overlapping parts. In any case, we should worry about this
if we decide to use COMDAT.
- Jim Dehnert dehnert at sgi.com
(650)933-4272
More information about the cxx-abi-dev
mailing list