Language

The Free and Open Productivity Suite
Released: Apache OpenOffice 4.1.15

Author: Stephan Bergmann. Last changed: $Date: 2004/10/28 13:05:15 $.

How to design C++ classes that are part of the SDK salhelper/cppuhelper API

The following list gives instructions how to design a C++ class that shall be part of the API of either salhelper or cppuhelper (i.e., of any SDK shared library that has a C++ API that is not all-inline). The motivating force behind those instructions is to minimize the amount of global symbols (especially weak ones). The list also explains exactly which symbols corresponding to a class to export on which platform; see SDK Dynamic Library Versioning for details about adding exported symbols to dynamic libraries.

  1. Never define inline functions. (Neither explicitly nor implicitly, by defining a function within its class. Inline functions, especially constructors and destructors, often make it necessary to export certain symbols that could otherwise be left unexported.)

  2. Make sure that the compiler does not declare any implicit functions. (To avoid any implicitly defined inline functions, see point 1. Potential implicit functions are default constructors, copy constructors, destructors, and copy assignment operators. The easiest way to avoid them is to declare a destructor, at least one copy constructor, and at least one copy assignment operator for each class; those declared functions that shall not be available can be declared private and left undefined.)

  3. Define every destructor that is declared. (Even a destructor that is declared pure virtual, to avoid any implicitly defined inline functions, see point 1.)

  4. If a class type (possibly cv-qualified, and possibly nested within pointer or reference types) is ever used either

    • as a type-id within a dynamic_cast expression that needs to be evaluated at runtime,
    • as the static type of an expression within a dynamic_cast expression that needs to be evaluated at runtime,
    • as a type-id within a typeid expression,
    • as the static type of an expression within a typeid expression,
    • as the static type of an assignment-expression within a throw expression, or
    • within the exception-declaration of a catch handler,

    then declare its destructor virtual. (To have a dedicated place where RTTI for that class is generated. Since in general you cannot control the ways a class is used, the best advice probably is to do this for each class that is intended to be either used as an exception or subclassed.)

  5. If the destructor of a class is declared virtual, declare the destructors of all its base classes virtual. (To have a dedicated place where RTTI for the base classes is generated, which is referenced by the RTTI for the derived class. Since in general you cannot control the ways a class is used, the best advice probably is to do this for each class that is intended to be subclassed.)

  6. Special symbols to be exported for GCC 3:

    • For each constructor that shall be available outside the dynamic library, export any corresponding C1 and C2 variant symbols.
    • For each destructor that shall be available outside the dynamic library, export any corresponding D0, D1, and D2 variant symbols. (The D0 variant seems to be never called directly, but only be referenced from the vtable, but that is no guarantee that this will not change in a future GCC version.)
    • For each class that is used outside the dynamic library in ways covered by point 4 plus recursive application of point 5, export the corresponding _ZTI and _ZTS symbols. (Strictly speaking, the _ZTS symbol need only be exported if the type is ever used as an incomplete type.)
    • It is known that some classes are used in ways covered by point 4 plus recursive application of point 5, and those classes have no dedicated place where RTTI for them is generated, and thus weak RTTI symbols are emitted wherever needed (classes affected by this are, for example, the all-inline classes representing UNO exception types, and all-inline exception classes like rtl::MalformedUriException; specifically not affected are the standard exception classes std::bad_alloc, std::bad_cast, std::bad_exception, std::bad_typeid, std::domain_error, std::exception, std::invalid_argument, std::ios_base::failure, std::length_error, std::logic_error, std::out_of_range, std::overflow_error, std::range_error, std::runtime_error, and std::underflow_error, as they all have dedicated places for their RTTI symbols in libstlport_gcc.so or libstdc++.so.5). To make those uses work under GCC 3, all involved load objects have to bind the same definitions of those symbols at runtime. To achieve this, the OOo build environment enforces that all global _ZTI and _ZTS symbols defined within a load object (as either weak or normal symbols) are indeed exported (with version GCC_3_0_0, in case the respective load object uses symbol versioning). This implies that any _ZTI and _ZTS symbols covered by the previous point are always exported with version GCC_3_0_0, which defeats the correct use of versioning for those symbols.
  7. Special symbols to be exported for Sun C++ 5:

    • For each constructor that shall be available outside the dynamic library, export any corresponding plain and #Nvariant 1 variant symbols.
    • For each destructor that shall be available outside the dynamic library, export any corresponding plain and #Nvariant 1 variant symbols.
    • For each class that is used outside the dynamic library in ways covered by point 4 plus recursive application of point 5, export the corresponding __RTTI__ symbols (of which there are three, one for the class itself, one for an unqualified pointer to the class, and one for a const-qualified pointer to the class).
  8. Special symbols to be exported for Microsoft Visual C++:

    • For each constructor that shall be available outside the dynamic library, export the corresponding symbol.
    • For each destructor that shall be available outside the dynamic library, export the corresponding symbol (do not export any `scalar deleting destructor' or `vector deleting destructor' symbols).

Apache Software Foundation

Copyright & License | Privacy | Contact Us | Donate | Thanks

Apache, OpenOffice, OpenOffice.org and the seagull logo are registered trademarks of The Apache Software Foundation. The Apache feather logo is a trademark of The Apache Software Foundation. Other names appearing on the site may be trademarks of their respective owners.