Issue summaries and status

Jim Dehnert dehnert at baalbek.engr.sgi.com
Wed Jun 30 07:07:15 UTC 1999


Attached are the current summary, open, and closed lists.  Note that
I've incorporated some of the edited email into the open issues list.
Let me know if I've screwed anything up...

-------------- next part --------------
<HTML>

<HEAD>
<title>C++ ABI Summary</title>

<link rel=stylesheet href=small-table.css type="text/css">

<hr>

<font size=6><i><b>
<p>
C++ ABI Summary
</b></i></font>

<p>
<i>Revised 28 June 1999</i>

</center>

</HEAD>

<BODY>

<p>
See also the full
<a href=cxx-open.html>Open</a> and
<a href=cxx-closed.html>Closed</a> issues lists.

<p>
<hr>

<p>
<h4>Meetings</h4>

<p>
<table align=center border=on cellpadding=3>

<tr class=small>
<th colspan=2> When </th>
<th> Where </th>
<th> Phone </th>
</tr>

<tr class=small>
<td> 24 June </td> <td> 10:00-12:00 PDT </td>
<td align=left colspan=2> completed </td>
</tr>

<tr class=small>
<td> 1 July </td>
<td> 10:00-12:00 PDT </td>
<td> SGI Sapphire 20L </td>
<td> 650-933-7976 </td>
</tr>

<tr class=small>
<td> 8 July </td>
<td> 10:00-12:00 PDT </td>
<td> SGI Sapphire 20L </td>
<td> 650-933-7976 </td>
</tr>

<tr class=small>
<td> 15 July </td>
<td> 10:00-12:00 PDT </td>
<td> SGI Sapphire 20L </td>
<td> 650-933-7976 </td>
</tr>

<tr class=small>
<td> 22 July </td>
<td> 10:00-12:00 PDT </td>
<td> SGI Sapphire 20L </td>
<td> 650-933-7976 </td>
</tr>

<tr class=small>
<td> 29 July </td>
<td> 10:00-12:00 PDT </td>
<td> SGI Sapphire 20L </td>
<td> 650-933-7976 </td>
</tr>

<tr class=small>
<td> 5 August </td>
<td> 10:00-12:00 PDT </td>
<td> SGI Sapphire 20L </td>
<td> 650-933-7976 </td>
</tr>

<tr class=small>
<td> 12 August </td>
<td> 10:00-12:00 PDT </td>
<td> SGI Sapphire 20L </td>
<td> 650-933-7976 </td>
</tr>

<tr class=small>
<td> 19 August </td>
<td> 10:00-12:00 PDT </td>
<td> SGI Sapphire 20L </td>
<td> 650-933-7976 </td>
</tr>

</table>

<p>
Note:  When calling the SGI telephone bridges,
the first caller continues to ring until the second party joins.
To get rid of it, you can call from a second phone,
and I believe you can hang it up right away.

<p>
<hr>

<p>
<h4>Participants</h4>

<p>
<table border=on cellpadding=3>

<tr class=small>
<th> Company </th>
<th> Name </th>
<th> Telephone </th>
<th> Fax </th>
<th> Email </th>
</tr>

<tr class=tiny>
<th rowspan=1> </th>
<td colspan=3> overall reflector </td>
<td> <a href=mailto:cxx-abi at postofc.corp.sgi.com>cxx-abi at corp.sgi.com</a> </td>
</tr>

<tr class=tiny>
<th rowspan=6> SGI </th>
<td> Jim Dehnert </td>
<td> (650) 933-4272 </td>
<td> (650) 932-4272 </td>
<td> <a href=mailto:dehnert at sgi.com> dehnert at sgi.com </a></td>
</tr>
<tr class=tiny>
<td> Matt Austern </td>
<td> (650) 933-4196 </td>
<td> (650) 932-4196 </td>
<td> <a href=mailto:austern at engr.sgi.com> austern at engr.sgi.com </a></td>
</tr>
<tr class=tiny>
<td> Hans Boehm </td>
<td> (650) 933-7144 </td>
<td> (650) 932-7144 </td>
<td> <a href=mailto:boehm at engr.sgi.com> boehm at engr.sgi.com </a></td>
</tr>
<tr class=tiny>
<td> Shin-Ming Liu </td>
<td> (650) 933-4287 </td>
<td> (650) 932-4287 </td>
<td> <a href=mailto:shin at engr.sgi.com> shin at engr.sgi.com </a></td>
</tr>
<tr class=tiny>
<td> John Wilkinson </td>
<td> (650) 933-4298 </td>
<td> (650) 932-4298 </td>
<td> <a href=mailto:jfw at engr.sgi.com> jfw at engr.sgi.com </a></td>
</tr>
<tr class=tiny>
<td colspan=3> reflector </td>
<td> <a href=mailto:cxx-abi-sgi at engr.sgi.com>
cxx-abi-sgi at engr.sgi.com </a></td>
</tr>

<tr class=tiny>
<th rowspan=4> Cygnus </th>
<td> Jason Merrill </td>
<td> (408) 542-9665 </td>
<td> (408) 542-9765 </td>
<td> <a href=mailto:jason at cygnus.com> jason at cygnus.com </a></td>
</tr>
<tr class=tiny>
<td> Ian Carmichael </td>
<td> (416) 482-3946 </td>
<td> (416) 482-6299 </td>
<td> <a href=mailto:iancarm at cygnus.com> iancarm at cygnus.com </a></td>
</tr>
<tr class=tiny>
<td> Ulrich Drepper </td>
<td> (408) 765-4699 </td>
<td> ? </td>
<td> <a href=mailto:drepper at cygnus.com> drepper at cygnus.com </a></td>
</tr>
<tr class=tiny>
<td colspan=3> reflector </td>
<td> <a href=mailto:c++abi at cygnus.com> c++abi at cygnus.com </a></td>
</tr>

<tr class=tiny>
<th rowspan=1> EDG </th>
<td> Daveed Vandevoorde </td>
<td> ? </td>
<td> ? </td>
<td> <a href=mailto:daveed at edg.com> daveed at edg.com </a></td>
</tr>

<tr class=tiny>
<th rowspan=1> EPC </th>
<td> Colin McPhail </td>
<td> +44 (131) 225-6262 </td>
<td> +44 (131) 225-6644 </td>
<td> <a href=mailto:colin at epc.co.uk> colin at epc.co.uk </a></td>
</tr>

<tr class=tiny>
<th rowspan=4> Hewlett- Packard </th>
<td> Cary Coutant </td>
<td> (408) 447-5759 </td>
<td> ? </td>
<td> <a href=mailto:cary at cup.hp.com> cary at cup.hp.com </a></td>
</tr>
<tr class=tiny>
<td> Christophe de Dinechin </td>
<td> (408) 447-5491 </td>
<td> ? </td>
<td> <a href=mailto:ddd at cup.hp.com> ddd at cup.hp.com </a></td>
</tr>
<tr class=tiny>
<td> Sassan Hazeghi </td>
<td> (408) 447-5007 </td>
<td> ? </td>
<td> <a href=mailto:sassan at cup.hp.com> sassan at cup.hp.com </a></td>
</tr>
<tr class=tiny>
<td colspan=3> reflector </td>
<td> <a href=mailto:cxx-abi-hp at cllmail.cup.hp.com>
cxx-abi-hp at cllmail.cup.hp.com </a></td>
</tr>

<tr class=tiny>
<th rowspan=3> IBM </th>
<td> Mark Mendell </td>
<td> (416) 448-3485 </td>
<td> (416) 448-4414 </td>
<td> <a href=mailto:mendell at ca.ibm.com> mendell at ca.ibm.com </a></td>
</tr>
<tr class=tiny>
<td> Allan H. Kielstra </td>
<td> (416) 448-3558 </td>
<td> (416) 448-4414 </td>
<td> <a href=mailto:kielstra at ca.ibm.com> kielstra at ca.ibm.com </a></td>
</tr>
<tr class=tiny>
<td colspan=3> reflector </td>
<td> <a href=mailto:CxxABI-ADTC-CAN at ca.ibm.com>
CxxABI-ADTC-CAN at ca.ibm.com </a></td>
</tr>

<tr class=tiny>
<th rowspan=4> Intel </th>
<td> Sunil Saxena </td>
<td> (408) 765-5272 </td>
<td> (408) 653-8511 </td>
<td> <a href=mailto:Sunil.Saxena at Intel.com> Sunil.Saxena at Intel.com </a></td>
</tr>
<tr class=tiny>
<td> Suresh Rao </td>
<td> (408) 765-5416 </td>
<td> (408) 765-5165 </td>
<td> <a href=mailto:Suresh.K.Rao at Intel.com>
Suresh.K.Rao at Intel.com </a></td>
</tr>
<tr class=tiny>
<td> Priti Shrivastav </td>
<td> (408) 765-4699 </td>
<td> (408) 765-5165 </td>
<td> <a href=mailto:Priti.Shrivastav at Intel.com>
Priti.Shrivastav at Intel.com </a></td>
</tr>
<tr class=tiny>
<td colspan=3> reflector </td>
<td> <a href=mailto:cxx-abi at unix-os.sc.intel.com>
cxx-abi at unix-os.sc.intel.com </a></td>
</tr>

<tr class=tiny>
<th rowspan=1> SCO </th>
<td> Jonathan Schilling </td>
<td> (908) 790-2364 </td>
<td> (908) 790-2426 </td>
<td> <a href=mailto:jls at sco.com> jls at sco.com </a></td>
</tr>

<tr class=tiny>
<th rowspan=4> Sun </th>
<td> George Vasick </td>
<td> (650) 786-5123 </td>
<td> (650) 786-9551 </td>
<td> <a href=mailto:george.vasick at eng.sun.com>
george.vasick at eng.sun.com <a></td>
</tr>
<tr class=tiny>
<td> Michael Lam </td>
<td> (650) 786-3492 </td>
<td> (650) 786-9551 </td>
<td> <a href=mailto:michael.lam at eng.sun.com> michael.lam at eng.sun.com </a></td>
</tr>
<tr class=tiny>
<td> Michael Ball </td>
<td> (650) 786-9109 </td>
<td> (650) 786-9551 </td>
<td> <a href=mailto:michael.ball at eng.sun.com> michael.ball at eng.sun.com </a></td>
</tr>
<tr class=tiny>
<td> Reza Monajjemi </td>
<td> (650) 786-6175 </td>
<td> ? </td>
<td> <a href=mailto:reza.monajjemi at eng.sun.com>
     reza.monajjemi at eng.sun.com </a></td>
</tr>

</table>

<p>
<hr>

<p>
<h4> Objectives </h4>

<ul>
<p>
<li>
Interoperable C++ compilation on IA-64:
we want users to be able to build relocatable objects with
different compilers and link them together,
and if possible even to ship common DSOs.
This objective implies agreement on:
    <ul>    
    <li> Data representation
    <li> Object file representation
    <li> Library API
    </ul>

<p>
<li>
ISO Standard C++:
highest priority is functionality and performance of standard-compliant code.
It should not be sacrificed for the benefit of language extensions or
legacy implementations (though considering them as tie-breakers is fine).

<p>
<li>
Some areas will be easier to agree on than others.
Our priorities should be based on achieving as much
interoperability as possible if we can't attain perfection.
That is, it is better to end up with a few restrictions being required
for interoperable code, than to have no interoperability at all.
This suggests priorities as follows:
    <ol>
    <li> Items requiring base ABI changes that might affect other
	languages, and will therefore become impossible soon.
	Examples include exception handling / stack unwind,
	or ELF changes (not extensions).
    <li> Core features where differences will prevent virtually any
	C++ object code from porting.
	Examples include data layout and calling conventions.
    <li> Limited usage features,
	where users can achieve portability by avoiding the feature.
	An example might be multi-threading.
    <li> Peripheral features,
	where the requirements on users to achieve
	portability are clear and easy to implement.
	An example is non-explicit inlining,
	where compilers would presumably allow it to just be suppressed.
    <li> Tool interfaces, which affect how users build code,
	rather than what they build.
	An example is the compilation command line.
    </ol>

<p>
<li>
Mechanisms/methods which allow coexistence of incompatible
implementations may be suitable in some cases.
For instance, packaging vendor-specific compiler support runtimes
in DSOs occupying distinct namespaces might allow multiple such DSOs to
be loaded for mixed objects and avoid requiring that all vendors have
the same support runtimes.

</ul>

<p>
<hr>

<p>
<h4> Action Item Status </h4>

<p>
<table border=on cellpadding=3>

<tr class=small>
<th> # </th>
<th> Action </th>
<th> Who </th>
<th> Status </th>
<th> Opened </th>
<th> Closed </th>
</tr>

<tr class=small> <td> 1 </td>
<td> Distribute Sun C++ ABI </td>
<td> Mike Ball </td>
<td> open </td>
<td> 990603 </td>
<td> </td>
</tr>

<tr class=small> <td> 2 </td>
<td> Distribute Sun C++ ABI Rationale </td>
<td> Mike Ball </td>
<td> open </td>
<td> 990603 </td>
<td> </td>
</tr>

<tr class=small> <td> 3 </td>
<td> Distribute Taligent C++ ABI </td>
<td> Cary Coutant </td>
<td> open </td>
<td> 990603 </td>
<td> </td>
</tr>

<tr class=small> <td> 4 </td>
<td> Expedite IA-64 RT Arch doc release </td>
<td> Cary Coutant </td>
<td> open </td>
<td> 990603 </td>
<td> </td>
</tr>

<tr class=small> <td> 5 </td>
<td> Set up n-way NDA for eligible members </td>
<td> Priti Shrivastav </td>
<td> open </td>
<td> 990603 </td>
<td> </td>
</tr>

<tr class=small> <td> 6 </td>
<td> Organize/summarize object layout issues and alternatives </td>
<td> Matt Austern </td>
<td> closed </td>
<td> 990603 </td>
<td> 990624 </td>
</tr>

<tr class=small> <td> 7 </td>
<td> Write-up of Vtable issues,
     including Vtable layout, Vfunc call protocol
</td>
<td> Christophe de Dinechin </td>
<td> open </td>
<td> 990610 </td>
<td> </td>
</tr>

<tr class=small> <td> 8 </td>
<td> Write-up of object layout strawman </td>
<td> Matt Austern </td>
<td> closed </td>
<td> 990610 </td>
<td> 990624 </td>
</tr>

<tr class=small> <td> 9 </td>
<td> Check with c++-core about empty base placement </td>
<td> Jason Merrill </td>
<td> open </td>
<td> 990610 </td>
<td> 990618 </td>
</tr>

<tr class=small> <td> 10 </td>
<td> Describe dynamic cast / inaccessible base issue </td>
<td> Daveed Vandevoorde </td>
<td> open </td>
<td> 990617 </td>
<td> </td>
</tr>

<tr class=small> <td> 11 </td>
<td> Summarize ctor/dtor issues </td>
<td> Michael Lam </td>
<td> open </td>
<td> 990617 </td>
<td> </td>
</tr>

<tr class=small> <td> 12 </td>
<td> Describe Intel exception model </td>
<td> Priti Shrivastav </td>
<td> open </td>
<td> 990624 </td>
<td> </td>
</tr>


</table>

<p>
<hr>

<p>
<h4> Issue Status </h4>

In the following table,
the <b><i>class</i></b> column attempts to classify the issue on the
basis of what it likely affects.
The identifiers used are:

<table>
<tr class=small> <td> call </td>
<td> Function call interface, i.e. call linkage </td>
</tr>

<tr class=small> <td> data </td>
<td> Data layout </td>
</tr>

<tr class=small> <td> lib </td>
<td> Runtime library support </td>
</tr>

<tr class=small> <td> lif </td>
<td> Library interface, i.e. API </td>
</tr>

<tr class=small> <td> g </td>
<td> Potential gABI impact </td>
</tr>

<tr class=small> <td> ps </td>
<td> Potential psABI impact </td>
</tr>

<tr class=small> <td> source </td>
<td> Source code conventions (i.e. API, not ABI) </td>
</tr>

<tr class=small> <td> tools </td>
<td> May affect how program construction tools interact </td>
</tr>
</table>

<p>
<hr width=50%>

<p>
<table border=on cellpadding=3>

<tr class=small>
<th> # </th>
<th> Issue </th>
<th> Class </th>
<th> Status </th>
<th> Source </th>
<th> Opened </th>
<th> Closed </th>
</tr>

<tr class=small> </tr>
<tr class=small> <th> A </th>
<th colspan=6> <a href=issues-C++-layout.html> Object Layout </a> </th>
</tr>

<tr class=small> <td> A-1 </td>
<td> Vptr location </td>
<td> data </td>
<td> closed </td>
<td> SGI </td>
<td> 990520 </td>
<td> 990624 </td>
</tr>

<tr class=small> <td> A-2 </td>
<td> Virtual base classes </td>
<td> data </td>
<td> closed </td>
<td> SGI </td>
<td> 990520 </td>
<td> 990624 </td>
</tr>

<tr class=small> <td> A-3 </td>
<td> Multiple inheritance </td>
<td> data </td>
<td> open </td>
<td> SGI </td>
<td> 990520 </td>
<td> </td>
</tr>

<tr class=small> <td> A-4 </td>
<td> Empty base classes </td>
<td> data </td>
<td> closed </td>
<td> SGI </td>
<td> 990520 </td>
<td> 990624 </td>
</tr>

<tr class=small> <td> A-5 </td>
<td> Empty parameters </td>
<td> data </td>
<td> open </td>
<td> SGI </td>
<td> 990520 </td>
<td> </td>
</tr>

<tr class=small> <td> A-6 </td>
<td> RTTI (<code>type_info</code>) .o representation </td>
<td> data call ps </td>
<td> open </td>
<td> SGI </td>
<td> 990520 </td>
<td> </td>
</tr>

<tr class=small> <td> A-7 </td>
<td> Vptr sharing with primary base class </td>
<td> data </td>
<td> open </td>
<td> HP </td>
<td> 990603 </td>
<td> </td>
</tr>

<tr class=small> <td> A-8 </td>
<td> (Virtual) base class alignment </td>
<td> data </td>
<td> closed </td>
<td> HP </td>
<td> 990603 </td>
<td> 990624 </td>
</tr>

<tr class=small> <td> A-9 </td>
<td> Sorting fields as allowed by [class.mem]/12 </td>
<td> data </td>
<td> closed </td>
<td> HP </td>
<td> 990603 </td>
<td> 990624 </td>
</tr>

<tr class=small> <td> A-10 </td>
<td> Class parameters in registers </td>
<td> call </td>
<td> open </td>
<td> HP </td>
<td> 990603 </td>
<td> </td>
</tr>

<tr class=small> <td> A-11 </td>
<td> Representation of pointers to members </td>
<td> data </td>
<td> open </td>
<td> Cygnus </td>
<td> 990603 </td>
<td> </td>
</tr>

<tr class=small> <td> A-12 </td>
<td> Merging secondary vtables </td>
<td> data </td>
<td> open </td>
<td> HP </td>
<td> 990610 </td>
<td> </td>
</tr>

<tr class=small> <td> A-13 </td>
<td> Parameter struct field promotion </td>
<td> call </td>
<td> open </td>
<td> SGI </td>
<td> 990603 </td>
<td> </td>
</tr>

<tr class=small> </tr>
<tr class=small> <th> B </th>
<th colspan=6> <a href=issues-C++-layout.html#vfunc>
Virtual Function Handling </a> </th>
</tr>

<tr class=small> <td> B-1 </td>
<td> Adjustment of "this" pointer (e.g. thunks) </td>
<td> data call </td>
<td> open </td>
<td> SGI </td>
<td> 990520 </td>
<td> </td>
</tr>

<tr class=small> <td> B-2 </td>
<td> Covariant return types </td>
<td> call </td>
<td> open </td>
<td> SGI </td>
<td> 990520 </td>
<td> </td>
</tr>

<tr class=small> <td> B-3 </td>
<td> Allowed caching of vtable contents </td>
<td> call </td>
<td> open </td>
<td> HP </td>
<td> 990603 </td>
<td> </td>
</tr>

<tr class=small> <td> B-4 </td>
<td> Function descriptors in vtable </td>
<td> data </td>
<td> open </td>
<td> HP </td>
<td> 990603 </td>
<td> </td>
</tr>

<tr class=small> <td> B-5 </td>
<td> Where are vtables emitted? </td>
<td> data </td>
<td> open </td>
<td> HP </td>
<td> 990603 </td>
<td> </td>
</tr>

<tr class=small> <td> B-6 </td>
<td> Virtual function table layout </td>
<td> data </td>
<td> open </td>
<td> SGI </td>
<td> 990520 </td>
<td> </td>
</tr>

<tr class=small> <td> B-7 </td>
<td> Vtables in shared memory </td>
<td> data </td>
<td> open </td>
<td> HP </td>
<td> 990624 </td>
<td> </td>
</tr>

<tr class=small> <td> B-8 </td>
<td> dynamic_cast </td>
<td> data </td>
<td> open </td>
<td> SGI </td>
<td> 990628 </td>
<td> </td>
</tr>


<tr class=small> </tr>
<tr class=small> <th> C </th>
<th colspan=6> Object Construction/Destruction </th>
</tr>

<tr class=small> <td> C-1 </td>
<td> Interaction with .init/.fini </td>
<td> lif ps </td>
<td> open </td>
<td> SGI </td>
<td> 990520 </td>
<td> </td>
</tr>

<tr class=small> <td> C-2 </td>
<td> Order of ctors/dtors w.r.t. link </td>
<td> lif ps </td>
<td> open </td>
<td> HP </td>
<td> 990603 </td>
<td> </td>
</tr>

<tr class=small> <td> C-3 </td>
<td> Order of ctors/dtors w.r.t. DSOs </td>
<td> ps </td>
<td> open </td>
<td> HP </td>
<td> 990603 </td>
<td> </td>
</tr>

<tr class=small> <td> C-4 </td>
<td> Calling vfuncs in ctors/dtors </td>
<td> call </td>
<td> open </td>
<td> Cygnus </td>
<td> 990603 </td>
<td> </td>
</tr>

<tr class=small> <td> C-5 </td>
<td> Calling virtual destructors </td>
<td> call </td>
<td> open </td>
<td> Sun </td>
<td> 990603 </td>
<td> </td>
</tr>

<tr class=small> <td> C-6 </td>
<td> Extra parameters to ctors/dtors </td>
<td> call </td>
<td> open </td>
<td> Cygnus </td>
<td> 990603 </td>
<td> </td>
</tr>

<tr class=small> <td> C-7 </td>
<td> Passing value parameters by reference </td>
<td> call </td>
<td> open </td>
<td> All </td>
<td> 990625 </td>
<td> </td>
</tr>

<tr class=small> <td> C-8 </td>
<td> Returning classes with non-trival copy constructors </td>
<td> call </td>
<td> open </td>
<td> All </td>
<td> 990625 </td>
<td> </td>
</tr>


<tr class=small> </tr>
<tr class=small> <th> D </th>
<th colspan=6> Exception Handling </th>
</tr>

<tr class=small> <td> D-1 </td>
<td> Language-specific data area format </td>
<td> lib ps </td>
<td> open </td>
<td> SGI </td>
<td> 990520 </td>
<td> </td>
</tr>

<tr class=small> <td> D-2 </td>
<td> Unwind personality routines </td>
<td> lib ps </td>
<td> open </td>
<td> SGI </td>
<td> 990520 </td>
<td> </td>
</tr>

<tr class=small> <td> D-3 </td>
<td> Unwind process clarification </td>
<td> lib ps </td>
<td> open </td>
<td> SGI </td>
<td> 990520 </td>
<td> </td>
</tr>

<tr class=small> <td> D-4 </td>
<td> Unwind routines nested? </td>
<td> lib ps </td>
<td> open </td>
<td> SGI </td>
<td> 990520 </td>
<td> </td>
</tr>

<tr class=small> <td> D-5 </td>
<td> Interaction with other languages (e.g. Java) </td>
<td> lib ps </td>
<td> open </td>
<td> HP </td>
<td> 990603 </td>
<td> </td>
</tr>

<tr class=small> <td> D-6 </td>
<td> Allow resumption in other languages? </td>
<td> lib ps </td>
<td> open </td>
<td> HP </td>
<td> 990603 </td>
<td> </td>
</tr>

<tr class=small> <td> D-7 </td>
<td> Interaction with signals or asynch events </td>
<td> lib ps </td>
<td> open </td>
<td> HP </td>
<td> 990603 </td>
<td> </td>
</tr>

<tr class=small> <td> D-8 </td>
<td> Interaction with threads packages </td>
<td> lib ps </td>
<td> open </td>
<td> SGI </td>
<td> 990603 </td>
<td> </td>
</tr>


<tr class=small> </tr>
<tr class=small> <th> E </th>
<th colspan=6> Template Instantiation Model </th>
</tr>

<tr class=small> <td> E-1 </td>
<td> When does instantiation occur? </td>
<td> tools </td>
<td> open </td>
<td> SGI </td>
<td> 990520 </td>
<td> </td>
</tr>

<tr class=small> <td> E-2 </td>
<td> Separate compilation model </td>
<td> tools </td>
<td> open </td>
<td> SGI </td>
<td> 990520 </td>
<td> </td>
</tr>

<tr class=small> <td> E-3 </td>
<td> Template repository </td>
<td> tools </td>
<td> open </td>
<td> HP </td>
<td> 990603 </td>
<td> </td>
</tr>


<tr class=small> </tr>
<tr class=small> <th> F </th>
<th colspan=6> Name Mangling </th>
</tr>

<tr class=small> <td> F-1 </td>
<td> Mangling convention </td>
<td> call </td>
<td> open </td>
<td> SGI </td>
<td> 990520 </td>
<td> </td>
</tr>

<tr class=small> <td> F-2 </td>
<td> Mangled name size </td>
<td> call g </td>
<td> open </td>
<td> SGI </td>
<td> 990520 </td>
<td> </td>
</tr>

<tr class=small> <td> F-3 </td>
<td> Distinguish template instantiation and specialization
</td>
<td> call g </td>
<td> open </td>
<td> SGI </td>
<td> 990520 </td>
<td> </td>
</tr>


<tr class=small> </tr>
<tr class=small> <th> G </th>
<th colspan=6> Miscellaneous </th>
</tr>

<tr class=small> <td> G-1 </td>
<td> Basic command line options </td>
<td> tools </td>
<td> open </td>
<td> HP </td>
<td> 990603 </td>
<td> </td>
</tr>

<tr class=small> <td> G-2 </td>
<td> Detection of 1-def rule violations </td>
<td> call </td>
<td> open </td>
<td> Sun </td>
<td> 990603 </td>
<td> </td>
</tr>

<tr class=small> <td> G-3 </td>
<td> Inlined routine linkage </td>
<td> call </td>
<td> open </td>
<td> Sun </td>
<td> 990603 </td>
<td> </td>
</tr>

<tr class=small> <td> G-4 </td>
<td> Dynamic init of local static objects and multithreading </td>
<td> call </td>
<td> open </td>
<td> SCO </td>
<td> 990607 </td>
<td> </td>
</tr>

<tr class=small> </tr>
<tr class=small> <th> H </th>
<th colspan=6> Runtime Library Interface </th>
</tr>

<tr class=small> <td> H-1 </td>
<td> Runtime library DSO name </td>
<td> tools </td>
<td> open </td>
<td> SGI </td>
<td> 990616 </td>
<td> </td>
</tr>

<tr class=small> <td> H-1 </td>
<td> Runtime library API </td>
<td> lif </td>
<td> open </td>
<td> SGI </td>
<td> 990616 </td>
<td> </td>
</tr>


</table>

<p>
<hr>

<p>
<h4>Notes from 3 June 1999 </h4>

<ul>
<p>
<li> Introductions

<p>
<li> Objectives: see above

<p>
<li> Procedure

  <ul>
  <li> Meetings:  10-12 Thursdays at SGI for the near term.
  <li> Intel NDA:  Generally unnecessary.  Priti will set up n-way
       for eligible members for cases where needed.  Cary expects RT
       architecture/software conventions document to be released in the
       next month or two, removing most of the issues.
  <li> Communication:  Use of reflector encouraged for discussion.
       NDA communication will be handled with password-protected PDF
       once Intel sets up n-way.
  <li> Available documents:  Parties with existing, relevant documents
       (includes Sun, HP) will send them to group.
  <li> Intellectual property:  Participants don't expect problems with
       release of any of their IP.  Microsoft has extensive patents in
       the area, but they are excessively broad (covering obvious ideas
       and prior art), so expectation is that they are not a problem.
       Nonetheless, we should be aware of them.
  </ul>

<p>
<li> Issue Identification:  new issues reflected in status table.

</ul>

<p>
<h4>Notes from 10 June 1999 </h4>

<p>
Matt Austern presented an initial assessment of the object layout issues.
He categorized them as trivial
(requiring agreement, but without significant performance implications)
or significant.  The trivial issues are:

<ol>
<p>
<li> (A-1) Where is the Vptr stored in an object?
Given the absence of addressing modes with displacements on IA-64,
the consensus is at the beginning of the object.

<p>
<li> (A-9) What is the order of members in an object?
Discussion of the possibilities for reordering between access
specifications suggests that we might find significance here.

<p>
<li> (A-4) Empty base class optimization:
when can an empty base class be stored at the same offset as another member?

<p>
<li> (A-1) What is the order of the Vtable?

<p>
<li> (B-5) What is the external name of a global Vtable?

<p>
<li> (B-5) Where is a global Vtable emitted?

</ol>

<p>
The significant issues are:

<ol>
<p>
<li> (A-3) How are virtual functions handled given multiple inheritance?
That is, where is the "this" pointer adjusted?

<p>
<li> (A-2) How are virtual functions handled given virtual base types?

<p>
<li> (B-2) How are virtual functions with covariant return types handled?
That is, where is the result pointer adjusted?

<p>
<li> (A-6) How does RTTI interact with exceptions?

</ol>

<p>
<h4>Notes from 17 June 1999 </h4>

<p>
<b> Issues A-1, A-2, A-9</b> (Matt):
See the open issues list.

<p>
<b> Actions</b>:
Christophe will write a Vtable layout definition strawman,
including a description of covariant returns,
and more generally the virtual function protocol.
Daveed will write up the issue with dynamic casts and inaccessible bases.

<p>
Michael Lam will write summaries for the ctor/dtor issues for next week.

<p>
<hr>

<p>
Please send corrections to <a href=mailto:dehnert at sgi.com>Jim Dehnert</a>.


</BODY>
</HTML>
-------------- next part --------------
<HTML>

<HEAD>
<title>C++ ABI Open Issues</title>

<link rel=stylesheet href=small-table.css type="text/css">
<link rel=stylesheet href=code.css type="text/css">

<hr>

<font size=6><i><b>
<p>
C++ ABI Open Issues
</b></i></font>

<font size=-1>
<p>
<i>Revised 28 June 1999</i>

</center>

</HEAD>

<BODY>

<p> <hr> <p>
<h3> Revisions </h3>

<p>
<font color=blue>[990625]</font>
Closed A-1, A-2, A-4, A-8, A-9.
Additions to A-3, A-5, A-7, B-4, B-5, B-7, G-3, G-4.
New issues B-6, B-7, B-8, C-7, C-8.

<p>
<font color=blue>[990616]</font>
Added HP summaries.
Added sketchy notes from 990610 discussions (A and B issues).
A-10 was intended by HP as something different than I described,
so it was renamed, and a new issue A-13 opened as an SGI issue.
HP did not submit A-12, so relabeled as Sun's (is that right?).
Added library interface issues, H-1 and H-2.


<p> <hr> <p>
<h3> Definitions </h3>

<p>
The issues below make use of the following definitions:

<dl>

<p>
<dt> <i>empty class</i> </dt>
<dd>
A class with no non-static data members,
no virtual functions, no virtual base classes,
and no non-empty non-virtual base classes.)

<p>
<dt> <i>nearly empty class</i> </dt>
<dd>
A class, the objects of which contain only a Vptr.

<p>
<dt> <i>vague linkage</i> </dt>
<dd>
The treatment of entities --
e.g. inline functions, templates, vtables --
with external linkage that can be
defined in multiple translation units,
while the ODR requires that the program
behave as if there were only a single definition.

</dl>


<p> <hr> <p>
<h3> Issue Status </h3>

In the following sections,
the <b><i>class</i></b> of an issue attempts to classify it on the
basis of what it likely affects.
The identifiers used are:

<table>
<tr> <td> call </td>
<td> Function call interface, i.e. call linkage </td>
</tr>

<tr> <td> data </td>
<td> Data layout </td>
</tr>

<tr> <td> lib </td>
<td> Runtime library support </td>
</tr>

<tr> <td> lif </td>
<td> Library interface, i.e. API </td>
</tr>

<tr> <td> g </td>
<td> Potential gABI impact </td>
</tr>

<tr> <td> ps </td>
<td> Potential psABI impact </td>
</tr>

<tr> <td> source </td>
<td> Source code conventions (i.e. API, not ABI) </td>
</tr>

<tr> <td> tools </td>
<td> May affect how program construction tools interact </td>
</tr>
</table>

<p> <hr> <p>
<h3> Object Layout Issues </h3>

<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <td> A-1 </td>
<td> Vptr location </td>
<td> data </td>
<td> closed </td>
<td> SGI </td>
<td> 990520 </td>
<td> 990624 </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
Where is the Vptr stored in an object (first or last are the usual answers).
</td> </tr>

</table>

<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <td> A-2 </td>
<td> Virtual base classes </td>
<td> data </td>
<td> closed </td>
<td> SGI </td>
<td> 990520 </td>
<td> 990624 </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
Where are the virtual base subobjects placed in the class layout?
How are data member accesses to them handled?
</td> </tr>

</table>

<p>

<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <td> A-3 </td>
<td> Multiple inheritance </td>
<td> data </td>
<td> open </td>
<td> SGI </td>
<td> 990520 </td>
<td> </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
Define the class layout in the presence of multiple base classes.
</td> </tr>

</table>

<p>
<font color=blue>[990617 All]</font>
At offset zero is the Vptr whenever there is one,
as well as the primary base class if any (see A-7).
Also at offset zero is any number of empty base classes,
as long as that does not place multiple subobjects of the same type at
the same offset.
If there are multiple empty base classes such that placing two of them
at offset zero would violate this constraint, the first is placed there.
(First means in declaration order.)

<p>
All other non-virtual base classes are laid out in declaration order at
the beginning of the class.
All other virtual base subobjects will be allocated at the
end of the class, left-to-right, depth-first.

<p>
The above ignores issues of padding for alignment,
and possible reordering of class members to fit in padding areas.
See issue A-9.

<p>
<font color=blue>[990624 All]</font>
There remains an issue concerning the selection of the primary base
class (see A-7), but we are otherwise in agreement.
We will attempt to close this on 1 July, modulo A-7.

<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <td> A-4 </td>
<td> Empty base classes </td>
<td> data </td>
<td> closed </td>
<td> SGI </td>
<td> 990520 </td>
<td> 990624 </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
Where are empty base classes allocated?
</td> </tr>

</table>

<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <td> A-5 </td>
<td> Empty parameters </td>
<td> data </td>
<td> open </td>
<td> SGI </td>
<td> 990520 </td>
<td> </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
When passing a parameter with an empty class type by value,
what is the convention?
</td> </tr>

</table>

<p>
<font color=blue>[990623 SGI]</font>
We propose that no parameter slot be allocated to such parameters,
i.e. that no register be used,
and that no space in the parameter memory sequence be used.
This implies that the callee must allocate storage at a unique address
if the address is taken (which we expect to be rare).

<p>
<font color=blue>[990624 All]</font>
In addition to the address-taken case,
care is required if the object has a non-trivial copy constructor.
HP observes that in (some?) such cases,
they perform the construction at the call site and pass the object by
reference.

<p>
<font color=blue>[990625 SGI -- Jim]</font>
I understand that the Standard explicitly allows elimination of
even non-trivial copy construction in some cases.
Is this one of them?  Where should I look?
Also, of course, varargs processing for elided empty parameters would
need to be careful.

<p>
I have opened a new issue (C-7) for passing copy-constructed
parameters by reference.
Since doing so would turn an empty value parameter
into a non-empty reference parameter,
this issue can ignore such cases.

<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <td> A-6 </td>
<td> RTTI (<code>type_info</code>) .o representation </td>
<td> data call ps </td>
<td> open </td>
<td> SGI </td>
<td> 990520 </td>
<td> </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
[Christophe]
</td> </tr>

</table>

<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <td> A-7 </td>
<td> Vptr sharing with primary base class </td>
<td> data </td>
<td> open </td>
<td> HP </td>
<td> 990603 </td>
<td> </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
It is in general possible to share the virtual pointer with a
polymorphic base class (the <i>primary</i> base class).
Which base class do we use for this?
</td> </tr>

</table>

<p>
<font color=blue>[990617 All]</font>
It will be shared with the first polymorphic non-virtual base class,
or if none, with the first nearly empty polymorphic virtual base class.
(See A-2 for the definition of <i>nearly empty</i>.)

<p>
<font color=blue>[990624 All]</font>
HP noted that Taligent chooses a base class with virtual bases before
one without as the primary base class),
probably to avoid additional "this" pointer adjustments.
SGI observed that such a rule would prevent users from controlling the
choice by their ordering of the base classes in the declaration.
The bias of the group remains the above resolution,
but HP will attempt to find the Taligent rationale before this is decided.

<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <td> A-8 </td>
<td> (Virtual) base class alignment </td>
<td> data </td>
<td> closed </td>
<td> HP </td>
<td> 990603 </td>
<td> 990624 </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
A (virtual) base class may have a larger alignment constraint than a
derived class.
Do we agree to extend the alignment constraint to the derived class?
</td> </tr>

</table>

<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <td> A-9 </td>
<td> Sorting fields as allowed by [class.mem]/12 </td>
<td> data </td>
<td> closed </td>
<td> HP </td>
<td> 990603 </td>
<td> 990624 </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
The standard constrains ordering of class members in memory only if
they are not separated by an access clause.
Do we use an access clause as an opportunity to fill the gaps left by padding?
</td> </tr>

</table>

<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <td> A-10 </td>
<td> Class parameters in registers </td>
<td> call </td>
<td> open </td>
<td> HP </td>
<td> 990603 </td>
<td> </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
The C ABI specifies that small structs are passed in registers.
Does this apply to small non-POD C++ objects passed by value?
What about the copy constructor and <code>this</code> pointer in that case?
</td> </tr>

</table>

<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <td> A-11 </td>
<td> Representation of pointers to members </td>
<td> data </td>
<td> open </td>
<td> Cygnus </td>
<td> 990603 </td>
<td> </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
[Ian]
</td> </tr>

</table>

<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <td> A-12 </td>
<td> Merging secondary vtables </td>
<td> data </td>
<td> open </td>
<td> Sun </td>
<td> 990610 </td>
<td> </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
[Sun]
</td> </tr>

</table>

<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <td> A-13 </td>
<td> Parameter struct field promotion </td>
<td> call </td>
<td> open </td>
<td> SGI </td>
<td> 990603 </td>
<td> </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
It is possible to pass small classes either as memory images,
as is specified by the base ABI for C structs,
or as a sequence of parameters, one for each member.
Which should be done, and if the latter,
what are the rules for identifying "small" classes?
</td> </tr>

</table>

<p> <hr> <p>
<h3> Virtual Function Handling Issues </h3>

<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <td> B-1 </td>
<td> Adjustment of "this" pointer (e.g. thunks) </td>
<td> data call </td>
<td> open </td>
<td> SGI </td>
<td> 990520 </td>
<td> </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
There are several methods for adjusting the <i>this</i> pointer
for a member function call,
including thunks or offsets located in the vtable.
We need to agree on the mechanism used,
and on the location of offsets, if any are needed.
To maximize performance on IA64,
a slightly unusual approach such as using secondary entry points
to perform the adjustment may actually prove interesting. 
</td> </tr>

</table>

<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <td> B-2 </td>
<td> Covariant return types </td>
<td> call </td>
<td> open </td>
<td> SGI </td>
<td> 990520 </td>
<td> </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
There are several methods for adjusting the 'this' pointer of the
returned value for member functions with covariant return types.
We need to decide how this is done.
Return thunks might be especially costly on IA64,
so a solution based on returning multiple pointers may prove more interesting.
</td> </tr>

</table>

<p>
<font color=blue>[990610 Matt]</font>
One possibility is to have two Vtable entries,
which might point to different functions, different entrypoints,
or a real entrypoint and a thunk.
Another is to return two result pointers (base/derived),
and have the caller select the right one.

<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <td> B-3 </td>
<td> Allowed caching of vtable contents </td>
<td> call </td>
<td> open </td>
<td> HP </td>
<td> 990603 </td>
<td> </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
The contents of the vtable can sometimes be modified,
but the concensus is that it is nonetheless always allowed to "cache" elements,
i.e. to retain them in registers and reuse them,
whenever it is really useful.
However, this may sometimes break "beyond the standard" code,
such as code loading a shared library that replaces a virtual function.
Can we all agree when caching is allowed? 
</td> </tr>

</table>

<p>
<font color=blue>[990604 HP Christophe]</font>
Mike (Ball) gave me what I believe is an excellent definition of  
when caching is allowed.  I'd like him to present it.

<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <td> B-4 </td>
<td> Function descriptors in vtable </td>
<td> data </td>
<td> open </td>
<td> HP </td>
<td> 990603 </td>
<td> </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
For a runtime architecture where the caller is expected to load the GP
of the callee (if it is in, or may be in, a different DSO), e.g. HP/UX,
what should vtable entries contain?
One possibility is to put a function address/GP pair in the vtable.
Another is to include only the address of a thunk which loads the GP
before doing the actual call.

</td> </tr>

</table>

<p>
<font color=blue>[990624 All]</font>
Note that putting GP in the Vtable prevents putting it in shared memory.
See B-7.


<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <td> B-5 </td>
<td> Where are vtables emitted? </td>
<td> data </td>
<td> open </td>
<td> HP </td>
<td> 990603 </td>
<td> </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
In C++, there are various things with external linkage that can be
defined in multiple translation units,
while the ODR requires that the program
behave as if there were only a single definition.
>From the user's standpoint, this applies to inlines and templates.
>From the implementation's perspective,
it also applies to things like vtables and RTTI info.
(We call this <i>vague linkage</i>.)
</td> </tr>

</table>

<p>
<font color=blue>[990624 Cygnus -- Jason]</font>
There are several ways of dealing with vague linkage items:
<ol>
<li> Emit them everywhere and only use one.
<li> Use some heuristic to decide where to emit them.
<li> Use a database to decide where to emit them.
<li> Generate them at link time.
</ol>

<p>
#3 and #4 are feasible for templates,
but I consider them too heavyweight to be used for other things.

<p>
The typical heuristic for #2 is "with the first non-inline,
non-abstract virtual function in the class".
This works pretty well,
but fails for classes that have no such virtual function,
and for non-member inlines.
Worse, the heuristic may produce different results in different
translation units,
as a method could be defined inline after being declared non-inline
in the class body.
So we have to handle multiple copies in some cases anyway.

<p>
The way to handle this in standard ELF is weak symbols.
If all definitions are marked weak,
the linker will choose one
and the others will just sit there taking up space.

<p>
Christophe mentioned the other day that the HP compiler used the
typical heuristic above,
and handled the case of different results by encoding the
key function in the vtable name.
But this seems unnecessary when we can just choose one of multiple defns.

<p>
A better solution than weak symbols alone would be to set things up so
that the linker will discard the extra copies.
Various existing implementations of this are:

<ol>
<p>
<li>
The Microsoft PE/COFF defn includes support for COMDAT sections,
which key off of the first symbol defined.
One copy is chosen, others are discarded.
You can specify conditions to the linker
(must have same contents, must have same size).

<p>
<li>
The IBM XCOFF platform includes a garbage-collecting linker;
sections that are not referenced in a sweep from main are discarded.
In xlC, template instantiations are emitted in separate sections,
with encoded names;
at link time, one copy is renamed to the real mangled name,
and the others are discarded by garbage collection.
</ol>

<p>
The GNU ELF toolchain does a variant of #1 here;
any sections with names beginning with ".gnu.linkonce."
are treated as COMDAT sections.
It seems more sensible to me to key off of the section name
than the first symbol name as in PE.

<p>
The GNU linker recently added support for garbage collection,
and I've been thinking about changing our handling of vague
linkage to make use of it, but haven't.

<p>
I propose that the ia64 base ABI be extended to
provide for either COMDAT sections or garbage collection,
and that we use that support for vague linkage.

<p>
I further propose that we not use heuristics to
cut down the number of copies ahead of time;
they usually work fine, but can cause problems in some situations,
such as when not all of the class's members are in the same symbol space.
Does the ia64 ABI provide for controlling which symbols
are exported from a shared library?

<p>
A side issue: What do we want to do with
dynamically-initialized variables?
The same thing, or use COMMON?
I propose COMMON.

<p>
See also G-3, for vague linkage of inlined routines and their static variables.

<p>
<font color=blue>[990624 SGI summarizing others]</font>
HP uses COMDAT for many cases, keying from the symbol names.
HP also uses some heuristics.
HP observes that IA-64 objects will already be large.
>From the base ABI discussions,
any use of WEAK or COMMON symbols will need to take care not to depend
on vendor-specific treatment.

<p>
Defining a COMDAT mechanism doesn't preclude using heuristics to avoid
some copies up front.
A COMDAT mechanism should also specify how to get rid of associated
sections like debugging info, unless the identical mechanism works.

<p>
<font color=blue>[990629 HP -- Christophe]</font>
First, the "usual" heuristic
(which is usual because it dates back to Cfront)
is to emit vtables in the translation unit that contains  
the definition of the first non inline, non pure virtual function.  
That is, for:
<pre><code>
        struct X {
                void a();
                virtual void f() { return; }
                virtual void g() = 0;
                virtual void h();
                virtual void i();
        };
</code></pre>
the vtable is emitted only in the TU that contains the definition of h().

<p>
This breaks and becomes non-portable if:
<ul>
<li>There is no such thing. In that case,
    you generally emit duplicate versions of vtables
<li>There is a "change of mind",
    such as having the above class followed by:
    <code><p>
    <dd>inline void X::h() { f(); }
    </code>

<p>
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 :
<pre><code>
	int f() { return 1; }
	int x = f();	// Static (COMDAT) or Dynamic (COMMON) initialization?
</code></pre>

<p>
So I personally recommend that we put everything in COMDAT.


<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <td> B-6 </td>
<td> Virtual function table layout </td>
<td> data </td>
<td> open </td>
<td> SGI </td>
<td> 990520 </td>
<td> </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
What is the layout of the Vtable?
</td> </tr>

</table>

<p>
<font color=blue>[990624]</font>
Issue split from A-1.


<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <td> B-7 </td>
<td> Vtables in shared memory </td>
<td> data </td>
<td> open </td>
<td> HP </td>
<td> 990624 </td>
<td> </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
Is it possible to put the Vtable in shared memory?
</td> </tr>

</table>

<p>
<font color=blue>[990624 All]</font>
Note that putting GP in the Vtable prevents putting it in shared memory.
This interacts with B-4.

<p>
<font color=blue>[990624 HP -- Cary]</font>
For a C++ object to be placed into shared memory,
its vtable pointer must be valid in all processes
that are sharing that object.

<ol>
<p>
<li>
If the vtable can be placed in text, that would be fine,
but the vtable contains function pointers (or descriptors)
that require runtime relocation, so it must be in data.

<p>
<li>
We can place the vtables in shared memory,
but only if the function pointers/descriptors are valid in all processes.
The entry point addresses, which refer to shared text, should be shareable,
but the gp values may not be identical for all processes.
(RTTI pointers are also an issue,
and could be solved by putting the RTTI information in shared memory as well.)

<p>
<li>
We can place the vtables in private memory,
provided they are at the same address in all processes.
</ol>

<p>
One way or another,
we need a way of ensuring that a pointer from shared 
memory to private memory is valid in all processes,
which means that we will need a means to ensure that certain shared
library data segments can get mapped at the same address in all
processes that load those certain libraries.

<p>
My wild idea a few years ago was to put the vtables in shared memory
(by allocating and building them at load time, as Taligent did),
and store a shared library index in place of the gp value
in each function descriptor.
Each process would have its own table of gp values,
indexed by this shared library index,
but the index space would be managed system-wide.
The C++ runtime library would have been responsible for allocating
a new index for each unique C++ shared library loaded on the system,
then storing the process-local copy of the gp pointer in the 
appropriate slot of the table.

<p>
<font color=blue>[990628 SGI -- Jim]</font>
Note a further problem with vtables in shared memory (Cary's point 2).
If a virtual function comes from another DSO,
it may be pre-empted differently in different programs.
Hence, the function pointer itself is a problem even if the GP isn't.



<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <td> B-8 </td>
<td> dynamic_cast </td>
<td> data </td>
<td> open </td>
<td> SGI </td>
<td> 990628 </td>
<td> </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
What information to we put in the vtable to enable (a) dynamic_cast
from pointer-to-base to pointer-to-derived (including detection of
ambiguous base classes) and (b) dynamic_cast to void*?
</td> </tr>

</table>

<p> <hr> <p>
<h3> Object Construction/Destruction Issues </h3>

<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <td> C-1 </td>
<td> Interaction with .init/.fini </td>
<td> lif ps </td>
<td> open </td>
<td> SGI </td>
<td> 990520 </td>
<td> </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
Static objects with dynamic constructors must be constructed at
intialization time.
This is done via the executable object initialization functions that
are identified (in ELF) by the DT_INIT and DT_INITARRAY dynamic tags.
How should the compiler identify the constructors to be called in this way?
One traditional mechanism is to put calls in a .init section.
Another, used by HP, is to put function addresses in a .initarray section.
<p>
The dual question arises for static object destructors.
Again, the extant mechanisms include putting calls in a .fini section,
or putting function addresses in a .finiarray section.
<p>
Finally, which mechanism (DT_INIT or DT_INITARRAY, or the FINI versions)
should be used in linked objects?
The gABI, and the IA-64 psABI, will support both,
with DT_INIT being executed before the DT_INITARRAY elements.
</td> </tr>

</table>

<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <td> C-2 </td>
<td> Order of ctors/dtors w.r.t. link </td>
<td> lif ps </td>
<td> open </td>
<td> HP </td>
<td> 990603 </td>
<td> </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
Given that the compiler has identified constructor/destructor calls for
static objects in each relocatable object, in what order should the
static linker combine them in the linked executable object?
(The initialization order determines the finalization order,
as its opposite.)
</td> </tr>

</table>

<p>
<font color=blue>[990610 All]</font>
Meeting concensus is that the desirable order is right to left on the
link command line, i.e. last listed relocatable object is initialized
first.

<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <td> C-3 </td>
<td> Order of ctors/dtors w.r.t. DSOs </td>
<td> ps </td>
<td> open </td>
<td> HP </td>
<td> 990603 </td>
<td> </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
Given the constructor/destructor calls for each executable object
comprising a program, what is the order of execution between objects?
For constructors, there is not much question:
unless we choose some explicit means of control,
file-scope objects will be initialized by the DT_INIT/DT_INITARRAY
functions in the order determined by the base ABI order rules,
and local objects will be initialized in the order their containing
scopes are entered.
<p>
For destructors, the Standard requires opposite-order destruction,
which implies a runtime structure to keep track of the order.
Furthermore, the potential for dynamic unloading of a DSO
(e.g. by dlclose)
requires a mechanism for early destruction of a subset.
</td> </tr>

</table>

<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <td> C-4 </td>
<td> Calling vfuncs in ctors/dtors </td>
<td> call </td>
<td> open </td>
<td> Cygnus </td>
<td> 990603 </td>
<td> </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
[Michael Lam]
</td> </tr>

</table>

<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <td> C-5 </td>
<td> Calling virtual destructors </td>
<td> call </td>
<td> open </td>
<td> Sun </td>
<td> 990603 </td>
<td> </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
[Michael Lam]
</td> </tr>

</table>

<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <td> C-6 </td>
<td> Extra parameters to ctors/dtors </td>
<td> call </td>
<td> open </td>
<td> Cygnus </td>
<td> 990603 </td>
<td> </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
[Michael Lam]
</td> </tr>

</table>

<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <td> C-7 </td>
<td> Passing value parameters by reference </td>
<td> call </td>
<td> open </td>
<td> All </td>
<td> 990624 </td>
<td> </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
It may be desirable in some cases where a type has a non-trivial
copy constructor to pass value parameters of that type by performing
the copy at the call site and passing a reference.
</td> </tr>

</table>

<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <td> C-8 </td>
<td> Returning classes with non-trival copy constructors </td>
<td> call </td>
<td> open </td>
<td> All </td>
<td> 990625 </td>
<td> </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
How do we return classes with non-trivial copy constructors?
</td> </tr>

</table>

<p> <hr> <p>
<h3> Exception Handling Issues </h3>

<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <td> D-1 </td>
<td> Language-specific data area format </td>
<td> lib ps </td>
<td> open </td>
<td> SGI </td>
<td> 990520 </td>
<td> </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
[SGI]
</td> </tr>

</table>

<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <td> D-2 </td>
<td> Unwind personality routines </td>
<td> lib ps </td>
<td> open </td>
<td> SGI </td>
<td> 990520 </td>
<td> </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
[SGI]
</td> </tr>

</table>

<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <td> D-3 </td>
<td> Unwind process clarification </td>
<td> lib ps </td>
<td> open </td>
<td> SGI </td>
<td> 990520 </td>
<td> </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
[SGI]
</td> </tr>

</table>

<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <td> D-4 </td>
<td> Unwind routines nested? </td>
<td> lib ps </td>
<td> open </td>
<td> SGI </td>
<td> 990520 </td>
<td> </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
[SGI]
</td> </tr>

</table>

<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <td> D-5 </td>
<td> Interaction with other languages (e.g. Java) </td>
<td> lib ps </td>
<td> open </td>
<td> HP </td>
<td> 990603 </td>
<td> </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
The IA64 exceptions handling framework is largely language independent.
What is the behaviour of a C++ runtime receiving, for instance,
an exception thrown from Java?
Does it call terminate()?
Does it allow the exception to pass through C++ code with destructors
if there is no catch clause?
Does it allow the exception to be caught in a catch(...) provided this
catch(...) ends with a rethrow?
Does it allow even more?
</td> </tr>

</table>

<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <td> D-6 </td>
<td> Allow resumption in other languages? </td>
<td> lib ps </td>
<td> open </td>
<td> HP </td>
<td> 990603 </td>
<td> </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
The exception handling framework requires the interaction of the
runtime of all the languages "on the stack" during exception processing.
Some of these languages may have very different exception handling semantics.
What are the constraints we impose on the C++ exception handling runtime
to preserve the relative language neutrality of the EH framework?
Example: do we allow a handler to cleanup and resume at the point
where the exception was thrown?
</td> </tr>

</table>

<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <td> D-7 </td>
<td> Interaction with signals or asynch events </td>
<td> lib ps </td>
<td> open </td>
<td> HP </td>
<td> 990603 </td>
<td> </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
The Standard says that the behavior of anything other than
"pure C code" (POF) is implementation defined,
and warns (in a note) against using EH in a signal handler.
We should define what is supported,
possibly explicitly stating that signal handler code must be a POF.
We could allow any feature but exception handling to be used.
We could allow some EH routines to be called
(for instance, <code>uncaught_exception()</code>).
Or we could allow even an exception to be thrown,
if it does not exit the handler.
</td> </tr>

</table>

<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <td> D-8 </td>
<td> Interaction with threads packages </td>
<td> lib ps </td>
<td> open </td>
<td> SGI </td>
<td> 990603 </td>
<td> </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
What happens when an exception is not caught in the thread where raised?
What does uncaught_exception() return if another thread is currently
processing an exception?
</td> </tr>

</table>

<p> <hr> <p>
<h3> Template Instantiation Model Issues </h3>

<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>


<tr> </tr>
<tr> <th> E </th>
<th colspan=6> Template Instantiation Model </th>
</tr>

<tr> <td> E-1 </td>
<td> When does instantiation occur? </td>
<td> tools </td>
<td> open </td>
<td> SGI </td>
<td> 990520 </td>
<td> </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
There are two principal models for instantiation.
The <i>early instantiation</i> (or Borland) model performs all
instantiation at compile time,
potentially resulting in extra copies which are removed at link time.
The <i>pre-link instantiation</i> model identifies the required
instantiations prior to linking and instantiates them via a special
compile step.
</td> </tr>

</table>

<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <td> E-2 </td>
<td> Separate compilation model </td>
<td> tools </td>
<td> open </td>
<td> SGI </td>
<td> 990520 </td>
<td> </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
[SGI]
</td> </tr>

</table>

<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <td> E-3 </td>
<td> Template repository </td>
<td> tools </td>
<td> open </td>
<td> HP </td>
<td> 990603 </td>
<td> </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
Independent of the template instantiation model,
we need to make sure that whatever template persistent storage is used
by one vendor does not interact negatively with other vendors' mechanisms.
Issues:
  (1) Avoiding conflict on the name of any repository.
  (2) If .o files are used,
	describe how this information is to be preserved, ignored, etc.
  (3) Evaluate if tools such as make, ld, ar, or others, can
	break because .o files get written at unexpected times.
</td> </tr>

</table>

<p> <hr> <p>
<h3> Name Mangling Issues </h3>

<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <td> F-1 </td>
<td> Mangling convention </td>
<td> call </td>
<td> open </td>
<td> SGI </td>
<td> 990520 </td>
<td> </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
What rules shall be used for mangling names,
i.e. for encoding the information other than the source-level object
name necessary to resolve overloading?
</td> </tr>

</table>

<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <td> F-2 </td>
<td> Mangled name size </td>
<td> call g </td>
<td> open </td>
<td> SGI </td>
<td> 990520 </td>
<td> </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
Typical name mangling schemes to date typically begin to produce very
long names.  SGI routinely encounters multi-kilobyte names,
and increasing usage of namespaces and templates will make them worse.
This has a negative impact on object file size, and on linker speed.
<p>
SGI has considered solutions to this problem including modified string
tables and/or symbol tables to eliminate redundancy.
Cygnus, HP, and Sun have also considered or implemented approaches
which at least mitigate it.
</td> </tr>

</table>

<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <td> F-3 </td>
<td> Distinguish template instantiation and specialization
</td>
<td> call g </td>
<td> open </td>
<td> SGI </td>
<td> 990520 </td>
<td> </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
In order to allow detection of conflicting template instantiation
and specialization (in different translation units),
should we name them differently?
If we do so in an easily recognizable way,
the linker could check for conflicts and report the ODR violation.
</td> </tr>

</table>

<p> <hr> <p>
<h3> Miscellaneous Issues </h3>

<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <td> G-1 </td>
<td> Basic command line options </td>
<td> tools </td>
<td> open </td>
<td> HP </td>
<td> 990603 </td>
<td> </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
Can we agree on basic command line options (compiler and linker)
for fundamental functionality,
possibly allowing portable makefiles?
</td> </tr>

</table>

<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <td> G-2 </td>
<td> Detection of ODR violations </td>
<td> call </td>
<td> open </td>
<td> Sun </td>
<td> 990603 </td>
<td> </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
[Sun]
(See also F-3.)
</td> </tr>

</table>

<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <td> G-3 </td>
<td> Inlined routine linkage </td>
<td> call </td>
<td> open </td>
<td> Sun </td>
<td> 990603 </td>
<td> </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
Inline routines with external linkage require a method of handling
vague linkage (see B-5 for definition) for the out-of-line instance,
as well as for any static data they contain.
The latter includes string constants per [7.1.2]/4.
</td> </tr>

</table>

<p>
<font color=blue>[990624 Cygnus -- Jason]</font>
How should we handle local static variables in inlines?
G++ currently avoids this issue by suppressing
inlining of functions with local statics.
If we don't want to do that,
we'll need to specify a mangling for the statics,
and handle multiple copies like we do above.

<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <td> G-4 </td>
<td> Dynamic init of local static objects and multithreading </td>
<td> call </td>
<td> open </td>
<td> SCO </td>
<td> 990607 </td>
<td> </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
The Standard requires that local static objects with dynamic
constructors be initialized exactly once, the first time the containing
scope is entered.
Multi-threading renders the simple check of a flag before
initialization inadequate to prevent multiple initialization.
Should the ABI require locking for this purpose,
and if so, what are the necessary interfaces?
In addition to the locking of the initialization,
special exception handling treatment is required to deal with an
exception during construction.
</td> </tr>

</table>

<p>
<font color=blue>[990607 SCO -- Jonathan]</font>
The standard is mute on multiple threads of control in general, so 
there is no requirement in the language to support what I'm talking
about. But as a practical matter compilers have to do it (Watcom gave
a paper on their approach during the standardization process, if I
remember).  This example using UI/SVR4 threads will usually show
whether a compiler does it or not: 

<pre><code>
thr5.C:
// static local initialization and threads

#include <stdlib.h>
#define EXIT(a) exit(a)
#define THR_EXIT() thr_exit(0)

#include <thread.h>

int init_count = 0;
int start_count = 0;

int init()
{
  
        ::thr_yield();
        return ++init_count;
}

void* start(void* s)
{
  
        start_count++;
        static int i = init();
        if (i != 1) EXIT(5);
        THR_EXIT();
        return 0;
}
                
int main()
{
  
        thread_t t1, t2;
        if (::thr_create(0, 0, start, 0, 0L, &t1) != 0) EXIT(1);
        if (::thr_create(0, 0, start, 0, 0L, &t2) != 0) EXIT(2);
        if (::thr_join(t1, 0, 0) != 0) EXIT(3);
        if (::thr_join(t2, 0, 0) != 0) EXIT(4);
        if (start_count != 2)
                EXIT(6);
        if (init_count != 1)
                EXIT(7);
        THR_EXIT();
}
</code></pre>

<p>
When compiled with CC -Kthread thr5.C on UnixWare 7, for instance,
it passes by returning 0.  When compiled with CC -mt thr5.C on
Solaris/x86 C++ 4.2 (sorry don't have the latest version!), it
fails by returning 5.


<p>
<font color=blue>[990607 Sun -- Mike Ball]</font>
As far as I can tell, the language says that the automatic blocking 
issue isn't a valid approach.  It says what has to happen, and
it isn't that.

<p>
If you look at the entire statement you find that it reads:
<quote>
"Otherwise such an object is initialized the first time control passes
through its declaration; such an object is considered initialized upon
the completion of its initialization.
If the initialization exits by throwing an exception,
the initialization is not complete,
so it will be tried again the next time control enters the declaration.
If control re-enters the declaration (recursively)
while the object is being initialized,
the behavior is undefined."
</quote>

<p>
The word "recursively" is normative,
so eliminates that sentence from consideration.

<p>
One can, of course, make any extension to the language,
but in this case I think the extension invalidates some otherwise valid code.

<p>
The sentence I'm referring to is that the object is considered
initialized upon the completion of its initialization.
This is explicit, and the reason for it is covered in the following sentence,
which discusses an initialization that terminates with an exception.
A person catching such an exception has the right to try again
without danger that the static variable will be initialized in the meantime.

<p>
I don't see anything at all to justify semantics that say,
"after initialization is started, Any other threads of control are
blocked until that thread completes the initialization,
unless, of course, it executes by an exception,
in which case the other thread can do the initialization before the
exception handler gets a chance to try again, except...."
 Take an attempt to define the semantics as far as you like.

<p>
The problem is that there is no way for the compiler writer to know
what the programmer really wanted to do.
I can (and will at some other date, if necessary)
come up with scenarios justifying a variety of mutual exclusion policies,
including none.

<p>
The solution is to let the programmer write the mutual exclusion, the
same as we do for every other potential race condition.
It's a real mess, and, I claim, an unwise one to put in as an extension.

<p>
<font color=blue>[990608 HP -- Christophe]</font>
The semantics currently implemented in the HP aC++ compiler is as follows:
<ul>
<li> No two thread can enter a static initialization at the same time
<li> Threads are blocked until immediately after the static  
    initialization either succeeds or fails with an exception.
</ul>

<p>
There are details of our implementation that I disagree with, but in  
general, the semantics seem clear and sane, not as convoluted as you  
seemed to imply. In particular, it correctly covers the case where  
the static initialization fails with an exception. Any thread at that  
point can attempt the initialization.

<p>
<font color=blue>[990608 SCO -- Jonathan]</font>
Here's what the SCO UnixWare 7 C++ compiler does for IA-32,
from a (slightly sanitized) design document.
 It meets Jim's goal of having no overhead for non-threaded programs
and minimal overhead for threaded programs unless
actual contention occurs (infrequent),
and meets Mike's goal of handling exceptions in the initialization correctly
(although it doesn't guarantee that the thread getting the exception is
the one that gets next crack at initializing the static).
 It's also worth noting that dynamic initialization of local variables
(static or otherwise) is very common in C++,
since that's what most object constructions involve,
so I don't think this case is as rare as Jim does.


<p>
[...] This is in local static variables with dynamic initialization,
where the compiler generates out a static one-time flag to guard the
initialization.
Two threads could read the flag as zero before either of them set it,
resulting in multiple initializations.

<p>
[...] Accordingly, when compilation is done with -Kthread on,
a code sequence will be generated to lock this initialization.  
[...] the basic idea is to have one guard saying whether the
initialization is done (so that multiple initializations do not occur)
and have another guard saying whether initialization is in progress
(so that a second thread doesn't access what it thinks is
an initialized value before the first thread has finished the
initialization).  [...]

<p>
When compiled with -Kthread, the generated code for a dynamic
initialization of a local static variable will look like the
following. guard is a local static boolean, initialized to zero,
generated by the [middle pass of the compiler]. 
Two bits of it are used: the low-order 'done bit'
and the next-low-order 'busy bit'.

<pre><code>
.again:
        movl    $guard,%eax
        testl   $1,(%eax)       // test the done bit
        jnz     .done           // if set, variable is initialized,
done
        lock; btsl  $1,(%eax)   // test and set the busy bit
        jc      .busy
        < init code >           // not busy, do the initialization
        movl    $guard,%eax
        movl    $3,(%eax)       // set the done bit
        jmp     .done
.busy:
        pushl   %eax            // call RTS routine to wait, passing address
        call1   __static_init_wait      // of guard to monitor
        testl   %eax,%eax       // 1 means exception occurred in init code,
        popl    %ecx
        jnz     .again                  // start the whole thing over
.done                                   // 0 means wait finished
</code></pre>

<p>
The above code will work for position-independent code as well.

The complication due to exceptions is:
what happens if the initialization code throws an exception?
The [compiler] EH tables will have set up a special region and flag in
their region table to detect this situation,
along with a pointer to the guard variable.
Because the initialization never completed,
when the RTS sees that it is cleaning up from such a region,
it will reset the guard variable back to both zeroes.
This will free up a busy-waiting thread, if any,
or will reset everything for the next thread that calls the function.

<p>
The idea of the __static_init_wait() RTS routine is to monitor the
value of guard bits passed in, by looping on this decision table:
<pre><code>
    done    busy
    0       0       return 1 in %eax        (EH wipe-out)
    1       1       return 0 in %eax        (no longer busy)
    0       1       continue to wait        (still busy)
    1       0       internal error, shouldn't happen
</code></pre>

<p>
As for how the wait is done [... not relevant for ABI,
although currently we're using thr_yield(),
which may or may not be right for this context].

<p>
<font color=blue>[990608 SGI -- Hans]</font>
I'd like to make some claims about function scope static constructor
calls in multithreaded environments.
I personally can't recall ever having used such a construct,
which somewhat substantiates my claims,
but also implies some lack of certainty.
I'd be interested in hearing any arguments to the contrary.

<p>
I believe that these arguments imply that this problem is not important
enough to warrant added ABI complexity or overhead for sequential code.

<p>
Consider the following skeletal example:

<p><code>
f(int x) { static foo a(...); ... }
</code>

<ol>
<p>
<li>
If the constructor argument doesn't depend on the function parameter,
and the code behaves reasonably, it should be possible to rewrite this as

<p><code>
static foo a(...);
<br>
f(int x) { ... }
</code>

<p>
<li>
If I read the standard correctly (and that's a big disclaimer),
the compiler is entitled to perform the above transformation under
conditions that are usually true,
but hard for the compiler to deduce.
Thus code that relies on the initialization occurring during the
execution of f is usually broken.

<p>
<li>
Thus the foo constructor cannot rely on its caller holding any locks.
It must explicitly acquire any locks it needs.

<p>
<li>
It is far preferable to write the transformed form with a file scope
static variable to start with.
The initial form risks deadlock,
since f may be called with locks held which the constructor
can't assume are held.
If it needs one of those locks it will need to reacquire it.
With default mutex semantics that results in deadlock with itself.
(If locks may be reentered,
it may fail in a more subtle manner since the foo constructor may
acquire a monitor lock whose monitor invariant doesn't hold.)

<p>
<li>
File scope static constructor calls aren't a problem and require no locking,
since they are executed in a single thread before main is called or
before dlopen returns.
(Forking a thread in a static constructor should probably be disallowed.
Threads may not have been fully initialized, among other issues.)

<p>
<li>
Static function scope constructor calls which depend on function
arguments are likely to involve a race condition anyway,
if multiple instances of the function can be invoked concurrently.
Any of the calls might determine the constructor parameters.
Thus these aren't very interesting either.
And if they are really needed, they can be replaced with a file scope
static constructor call plus an assignment.

</ol>



<p> <hr> <p>
<h3> Library Interface Issues </h3>

<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <td> H-1 </td>
<td> Runtime library DSO name </td>
<td> tools </td>
<td> open </td>
<td> SGI </td>
<td> 990616 </td>
<td> </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
Determine the name of the common C++ runtime library DSO,
e.g. <code>libC.so</code>.
If there are to be vendor-specific support libraries which must coexist
in programs from mixed sources, identify naming convention for them.
</td> </tr>

</table>

<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <td> H-2 </td>
<td> Runtime library API </td>
<td> lif </td>
<td> open </td>
<td> SGI </td>
<td> 990616 </td>
<td> </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
Define the required entrypoints in the common C++ runtime library DSO,
and their prototypes.
</td> </tr>

</table>

<p>
<hr>

<p>
Please send corrections to <a href=mailto:dehnert at sgi.com>Jim Dehnert</a>.


</BODY>
</HTML>
-------------- next part --------------
<HTML>

<HEAD>
<title>C++ ABI Closed Issues</title>

<link rel=stylesheet href=small-table.css type="text/css">
<link rel=stylesheet href=code.css type="text/css">

<hr>

<font size=6><i><b>
<p>
C++ ABI Closed Issues
</b></i></font>

<font size=-1>
<p>
<i>Revised 25 June 1999</i>

</center>

</HEAD>

<BODY>

<p> <hr> <p>
<h3> Issue Status </h3>

In the following sections,
the <b><i>class</i></b> of an issue attempts to classify it on the
basis of what it likely affects.
The identifiers used are:

<table>
<tr> <td> call </td>
<td> Function call interface, i.e. call linkage </td>
</tr>

<tr> <td> data </td>
<td> Data layout </td>
</tr>

<tr> <td> lib </td>
<td> Runtime library support </td>
</tr>

<tr> <td> lif </td>
<td> Library interface, i.e. API </td>
</tr>

<tr> <td> g </td>
<td> Potential gABI impact </td>
</tr>

<tr> <td> ps </td>
<td> Potential psABI impact </td>
</tr>

<tr> <td> source </td>
<td> Source code conventions (i.e. API, not ABI) </td>
</tr>

<tr> <td> tools </td>
<td> May affect how program construction tools interact </td>
</tr>
</table>

<p> <hr> <p>
<h3> A.  Object Layout Issues </h3>

<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <td> A-1 </td>
<td> Vptr location </td>
<td> data </td>
<td> closed </td>
<td> SGI </td>
<td> 990520 </td>
<td> 990624 </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
Where is the Vptr stored in an object (first or last are the usual answers).
</td> </tr>

</table>

<p>
<font color=blue>[990610 All]</font>
Given the absence of addressing modes with displacements on IA-64,
the consensus is to answer this question with "first."

<p>
<font color=blue>[990617 All]</font>
Given a Vptr and only non-polymorphic bases,
which (Vptr or base) goes at offset 0?
<ul>
<li> HP: Vptr at end, but IA-64 is different because no load displacement
<li> Sun: Vptr at 0 probably preferred
<li> g++: Vptr at end today
</ul>
<p>
Tentative decision:  Vptr always goes at beginning.

<p>
<font color=blue>[990624 All]</font>
Accepted tentative decision.
Rename, close this issue, and open separate issue (B-6) for Vtable layout.

<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <td> A-2 </td>
<td> Virtual base classes </td>
<td> data </td>
<td> closed </td>
<td> SGI </td>
<td> 990520 </td>
<td> 990624 </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
Where are the virtual base subobjects placed in the class layout?
How are data member accesses to them handled?
</td> </tr>

</table>

<p>
<font color=blue>[990610 Matt]</font>
With regard to how data member accesses are handled,
the choices are to store either a pointer or an offset in the Vtable.
The concensus seems to be to prefer an offset.

<p>
<font color=blue>[990617 All]</font>
Any number of empty virtual base subobjects (rare) will be placed at
offset zero.
If there are no non-virtual polymorphic bases,
the first virtual base subobject with a Vpointer will be placed at
offset zero.
Finally, all other virtual base subobjects will be allocated at the
end of the class, left-to-right, depth-first.

<p>
<font color=blue>[990624 All]</font>
Define an empty object as one with no non-static, non-empty data members,
no virtual functions,
no virtual base classes,
and no non-empty non-virtual base classes.
Define a nearly empty object as one which contains only a Vptr.
The above resolution is accepted, restated as follows:

<p>
Any number of empty virtual base subobjects
(rare, because they cannot have virtual functions or bases themselves)
will be placed at offset zero, subject to the conflict rules in A-3
(i.e. this cannot result in two objects of the same type at the same
address).
If there are no non-virtual polymorphic base subobjects,
the first nearly empty virtual base subobject will be placed at offset zero.
Any virtual base subobjects not thus placed at offset zero will be
allocated at the end of the class,
in left-to-right, depth-first declaration order.

<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <td> A-4 </td>
<td> Empty base classes </td>
<td> data </td>
<td> closed </td>
<td> SGI </td>
<td> 990520 </td>
<td> 990624 </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
Where are empty base classes allocated?
(An empty base class is one with no non-static data members,
no virtual functions, no virtual base classes,
and no non-empty non-virtual base classes.)
</td> </tr>

</table>

<p>
<font color=blue>[990624 All]</font>
Closed as a duplicate of A-3.

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <td> A-8 </td>
<td> (Virtual) base class alignment </td>
<td> data </td>
<td> closed </td>
<td> HP </td>
<td> 990603 </td>
<td> 990624 </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
A (virtual) base class may have a larger alignment constraint than a
derived class.
Do we agree to extend the alignment constraint to the derived class?
(An alternative for virtual bases:
allow the virtual base to move in the complete object.)
</td> </tr>

</table>

<p>
<font color=blue>[990623 SGI]</font>
We propose that the alignment of a class be the maximum alignment of
its virtual and non-virtual base classes,
non-static data members, and Vptr if any.

<p>
<font color=blue>[990624 All]</font>
Above proposal accepted.
(SGI observation:
the size of the class is rounded up to a multiple of this alignment,
per the underlying psABI rules.)

<p>
<table border=on cellpadding=3>

<tr>
<th> # </th>
<th> Issue </th> <th> Class </th> <th> Status </th>
<th> Source </th> <th> Opened </th> <th> Closed </th>
</tr>

<tr> <td> A-9 </td>
<td> Sorting fields as allowed by [class.mem]/12 </td>
<td> data </td>
<td> closed </td>
<td> HP </td>
<td> 990603 </td>
<td> 990624 </td>
</tr>
<tr> <td colspan=7>
<b>Summary</b>:
The standard constrains ordering of class members in memory only if
they are not separated by an access clause.
Do we use an access clause as an opportunity to fill the gaps left by padding?
</td> </tr>

</table>

<p>
<font color=blue>[990610 all]</font>
Some participants want to avoid attempts to reorder members differently
than the underlying C struct ABI rules.
Others think there may be benefit in reordering later access sections
to fill holes in earlier ones, or even in base classes.

<p>
<font color=blue>[990617 all]</font>
There are several potential reordering questions, more or less independent:
<ol>
<li> Do we reorder whole access regions relative to one another?
<li> Do we attempt to fill padding in earlier access regions with
	initial members from later regions?
<li> Do we fill the tail padding of non-POD base classes with members from
	the current class?
<li> Do we attempt to fill interior padding of non-POD base classes with later
	members?
</ol>

<p>
There is no apparent support for (1),
since no simple heuristic has been identified with obvious benefits.
There is interest in (2), based on a simple heuristic which might
sometimes help and will never hurt.
However, it is not clear that it will help much,
and Sun objects on grounds that they prefer to match C struct layout.
Unless someone is interested enough to implement and run experiments,
this will be hard to agree upon.
G++ has implemented (3) as an option,
based on specific user complaints.
It clearly helps HP's example of a base class containing a word and flag,
with a derived class adding more flags.
Idea (4) has more problems, including some non-intuitive (to users) layouts,
and possibly complicating the selection of bitwise copy in the compiler.

<p>
<font color=blue>[990624 all]</font>
We will not do (1), (2), or (4).  We will do (3).
Specifically, allocation will be in modified declaration order as follows:
<ol>
<li> Vptr if any, and the primary base class per A-7.
<li> Any empty base classes allocated at offset zero per A-3.
<li> Any remaining non-virtual base classes.
<li> Any non-static data members.
<li> Any remaining virtual base classes.
</ol>
Each subobject allocated is placed at the next available position that
satisfies its alignment constraints, as in the underlying psABI.
This is interpreted with the following special cases:
<ol>
<li> The "next available position" after a class subobject
	(base class or data member) with tail padding is at the
	beginning of the tail padding, not after it.
<li> Empty classes are considered to have alignment and size 1,
	consisting solely of one byte of tail padding.
<li> Placement on top of the tail padding of an empty class must avoid
	placing multiple subobjects of the same type at the same
	address.
</ol>
After allocation is complete,
the size is rounded up to a multiple of alignment (with tail padding).

<p> <hr> <p>
<h3> B.  Virtual Function Handling Issues </h3>

<p> <hr> <p>
<h3> C.  Object Construction/Destruction Issues </h3>

<p> <hr> <p>
<h3> D.  Exception Handling Issues </h3>

<p> <hr> <p>
<h3> E.  Template Instantiation Model Issues </h3>

<p> <hr> <p>
<h3> F.  Name Mangling Issues </h3>

<p> <hr> <p>
<h3> G.  Miscellaneous Issues </h3>

<p> <hr> <p>
<h3> H.  Library Interface Issues </h3>

<p>
<hr>

<p>
Please send corrections to <a href=mailto:dehnert at sgi.com>Jim Dehnert</a>.

</BODY>
</HTML>


More information about the cxx-abi-dev mailing list