[cxx-abi-dev] Key functions and templates

Lawrence Crowl crowl at google.com
Mon Feb 22 23:45:25 UTC 2010


On 2/22/10, Zbigniew Sarbinowski <zibi at ca.ibm.com> wrote:
> Lawrence Crowl <crowl at google.com> wrote on 02/22/2010 04:50:46 PM:
> > On 2/22/10, Mark Mitchell <mark at codesourcery.com> wrote:
> > > Alasdair Grant wrote:
> > > > Implementations (at least of the ARM variant of the ABI) seem
> > > > to differ about whether the code above should define the vtable
> > > > for G_key_nodef<int>.  GCC 4.4 for ARM does define the vtable -
> > > > which suggests it is not treating G_key_nodef<int>::f() as a
> > > > key function (if it did, it could rely on some other unit to
> > > > be defining f(), and hence the vtable).
> > >
> > > Given that there is vague linkage involved, how does this matter?
> > > It sounds to me like GCC is being wasteful, in that it's defining
> > > a vtable not needed in this object file, and guaranteed to be
> > > present anyhow, but as vague linkage will collapse the definitions,
> > > it sounds like this is "just" a waste of space in object files,
> > > not in final executables.
> > >
> > > Even if -- as on Symbian, where I suspect this question arises :-)
> > > -- the waste makes it into a DSO, how is that an ABI conformance
> > > problem?
> >
> > How about the following scenario?
> >
> >   A translation unit declares an "extern template" specialization
> >   of G_key_defined<int>::f().  The compiler infers that the virtual
> >   table need not be generated even though the translation unit
> >   otherwise instantiates G_key_defined<int>.  The specialization of
> >   f() is not subsequently used, and so the vtable will fail to exist.
>
> I have a related issue for which I would like to get clarification.
> There seems to be a contradiction between ABI and C++ Standard.
> Given the following.
>
> /* t1.h */
> class A
> {
> virtual int foo() = 0;
> };
>
> struct B : public A
> {
> int foo();
> };
>
> /* t1.cpp */
> #include "t1.h"
> inline int B::foo() { return 55; }
>
> /* t2.cpp */
> #include "t1.h"
> int main()
> {
>   B b; // this line forces to generate vft
>   return b.foo();
> }
>
> The g++ compiler will compile and link fine since B::foo()
> will be generated as part of t1.o.  On the other hand, XL (IBM)
> compiler comes back with "Undefined symbol: .B::foo()".  This is
> because t1.o does not have its definition.  It was optimized out
> since XL didn't find any reference to it in t1.cpp.
>
> According to C++ Standard the above TC is invalid because it
> violates the last sentence from 3.2.3: "An inline function shall
> be defined in every translation unit in which it is used."
>
> However C++ABI by last sentence in sec. 5.2.3 (Virtual Tables)
> makes this TC valid.  "Note that if the key function is not
> declared inline in the class definition, but its definition later
> is always declared inline, it will be emitted in every object
> containing the definition."

One could argue that it is not "always declared inline" because
there is not inline declaration in t2.cpp.  That interpretation is
consistent with the standard, so I wouldn't want to rule it out.

-- 
Lawrence Crowl



More information about the cxx-abi-dev mailing list