Policies/Binary Compatibility Examples: Difference between revisions

    From KDE TechBase
    (Undo revision 43255: oops, this example was already there)
    (Add a section on changing CV qualifiers of data)
    Line 232: Line 232:
    |}
    |}


    == Change the CV-qualifiers ==
    == Change the CV-qualifiers of a member function ==
    {|
    {|
    |-
    |-
    Line 250: Line 250:
    public:
    public:
         int something();
         int something();
    };
    </code>
    |}
    == Change the CV-qualifiers of global data ==
    {|
    |-
    ! Before
    ! After
    |-
    | <code cppqt>
    // MSVC mangling: ?data@@3HA
    int data = 42;
    </code>
    | <code cppqt>
    // MSVC mangling: ?data@@3HB
    const int data = 42;
    </code>
    |-
    | <code cppqt>
    class MyClass
    {
    public:
        // MSVC mangling: ?data@MyClass@@2HA
        static int data;
    };
    </code>
    | <code cppqt>
    class MyClass
    {
    public:
        // MSVC mangling: ?data@MyClass@@2HB
        static const int data;
    };
    </code>
    |-
    | <code cppqt>
    class MyClass
    {
    public:
        static int data;
    };
    </code>
    | <code cppqt>
    class MyClass
    {
    public:
        // the compiler won't even create a symbol
        static const int data = 42;
    };
    };
    </code>
    </code>

    Revision as of 08:28, 15 July 2009

    This page is meant as examples of things you cannot do in C++ when maintaining binary compatibility.

    Unexport or remove a class

    Before After

    class KDECORE_EXPORT KUrl {

      // [...]
    

    };

    class KUrl {

      // [...]
    

    };

    Change the class hierarchy

    Before After

    class MyClass: public BaseClass {

      // [...]
    

    };

    class MyClass: public BaseClass, public OtherBaseClass {

      // [...]
    

    };

    class MyClass: public BaseClass1, public BaseClass2 {

      // [...]
    

    };

    class MyClass: public BaseClass2, public BaseClass1 {

      // [...]
    

    };

    Change the template arguments of a template class

    Before After

    template<typename T1> class MyTemplateClass {

       // [...]
    

    };

    template<typename T1, typename T2 = void> class MyTemplateClass {

       // [...]
    

    };

    Unexport a function

    Before After

    Q_CORE_EXPORT const char *qVersion();

    const char *qVersion();

    namespace KSocketFactory {

       KDECORE_EXPORT QTcpSocket *connectToHost(...);
    

    }

    namespace KSocketFactory {

       QTcpSocket *connectToHost(...);
    

    }

    Inline a function

    Before After

    int square(int n);

    inline int square(int n) { return n * n; }

    int square(int n) { return n * n; }

    inline int square(int n) { return n * n; }

    class Math {

       int square(int n);
    

    };

    // the following could be in a .cpp int Math::square(int n) { return n * n; }

    class Math {

       int square(int n);
    

    };

    // the following could be in a .cpp inline int Math::square(int n) { return n * n; }

    class Math {

       int square(int n);
    

    };

    // the following could be in a .cpp int Math::square(int n) { return n * n; }

    class Math {

       int square(int n)
       { return n * n; }
    

    };

    Change the parameters of a function

    Before After

    void doSomething(int i1, int i2);

    void doSomething(int i1, short i2);

    void doSomething(int i1, int i2);

    void doSomething(int i1, int i2, int i3 = 0);

    void doSomething(int i1);

    void doSomething(const int i1); // breaks with MSVC and Sun CC

    void doSomething(char *ptr);

    void doSomething(const char *ptr);

    Change the return type

    Before After

    QTcpSocket *createDevice();

    QIODevice *createDevice();

    Change the access rights

    Before After

    class MyClass { protected:

       void doSomething();
    

    };

    class MyClass { public:

       void doSomething();
    

    };

    Change the CV-qualifiers of a member function

    Before After

    class MyClass { public:

       int something() const;
    

    };

    class MyClass { public:

       int something();
    

    };

    Change the CV-qualifiers of global data

    Before After

    // MSVC mangling: ?data@@3HA int data = 42;

    // MSVC mangling: ?data@@3HB const int data = 42;

    class MyClass { public:

       // MSVC mangling: ?data@MyClass@@2HA
       static int data;
    

    };

    class MyClass { public:

       // MSVC mangling: ?data@MyClass@@2HB
       static const int data;
    

    };

    class MyClass { public:

       static int data;
    

    };

    class MyClass { public:

       // the compiler won't even create a symbol
       static const int data = 42;
    

    };

    Add a virtual member function to a class without any

    Before After

    struct Data {

       int i;
    

    };

    struct Data {

       int i;
       virtual int j();
    

    };

    Add new virtuals to a non-leaf class

    Before After

    class MyClass { public:

       virtual ~MyClass();
       virtual void foo();
    

    };

    class MyClass { public:

       virtual ~MyClass();
       virtual void foo();
       virtual void bar();
    

    };

    Change the order of the declaration of virtual functions

    Before After

    class MyClass { public:

       virtual ~MyClass();
       virtual void foo();
       virtual void bar();
    

    };

    class MyClass { public:

       virtual ~MyClass();
       virtual void bar();
       virtual void foo();
    

    };

    Override a virtual that doesn't come from a primary base

    class PrimaryBase { public:

       virtual ~PrimaryBase();
       virtual void foo();
    

    };

    class SecondaryBase { public:

       virtual ~PrimaryBase();
       virtual void bar();
    

    };

    Before After

    class MyClass: public PrimaryBase, public SecondaryBase { public:

       ~MyClass();
       void foo();
    

    };

    class MyClass: public PrimaryBase, public SecondaryBase { public:

       ~MyClass();
       void foo();
       void bar();
    

    };

    Override a virtual with a covariant return with different top address

    struct Data1 { int i; }; class BaseClass { public:

       virtual Data1 *get();
    

    };

    struct Data0 { int i; }; struct Complex1: Data0, Data1 { }; struct Complex2: virtual Data1 { };

    Before After

    class MyClass: public BaseClass { public: };

    class MyClass: public BaseClass { public:

       Complex1 *get();
    

    };

    class MyClass: public BaseClass { public: };

    class MyClass: public BaseClass { public:

       Complex2 *get();
    

    };