Policies/Binary Compatibility Examples: Difference between revisions

    From KDE TechBase
    (Add two examples of BC break when changing constness of parameters)
    (Replaced content with "{{Moved To Community}}")
     
    (14 intermediate revisions by 3 users not shown)
    Line 1: Line 1:
    This page is meant as examples of things you cannot do in C++ when maintaining [[Policies/Binary Compatibility Issues With C++|binary compatibility]].
    {{Moved To Community}}
     
    == Unexport or remove a class ==
    {|
    |-
    ! Before
    ! After
    |-
    | <code cppqt>
    class KDECORE_EXPORT KUrl
    {
      // [...]
    };
    </code>
    | <code cppqt>
    class KUrl
    {
      // [...]
    };
    </code>
    |}
     
    == Change the class hierarchy ==
    {|
    |-
    ! Before
    ! After
    |-
    | <code cppqt>
    class MyClass: public BaseClass
    {
      // [...]
    };
    </code>
    | <code cppqt>
    class MyClass: public BaseClass, public OtherBaseClass
    {
      // [...]
    };
    </code>
    |-
    | <code cppqt>
    class MyClass: public BaseClass1, public BaseClass2
    {
      // [...]
    };
    </code>
    | <code cppqt>
    class MyClass: public BaseClass2, public BaseClass1
    {
      // [...]
    };
    </code>
    |}
     
    == Change the template arguments of a template class ==
    {|
    |-
    ! Before
    ! After
    |-
    | <code cppqt>
    template<typename T1>
    class MyTemplateClass
    {
        // [...]
    };
    </code>
    | <code cppqt>
    template<typename T1, typename T2 = void>
    class MyTemplateClass
    {
        // [...]
    };
    </code>
    |}
     
    == Unexport a function ==
    {|
    |-
    ! Before
    ! After
    |-
    | <code cppqt>
    Q_CORE_EXPORT const char *qVersion();
    </code>
    | <code cppqt>
    const char *qVersion();
    </code>
    |-
    | <code cppqt>
    namespace KSocketFactory {
        KDECORE_EXPORT QTcpSocket *connectToHost(...);
    }
    </code>
    | <code cppqt>
    namespace KSocketFactory {
        QTcpSocket *connectToHost(...);
    }
    </code>
    |}
     
    == Inline a function ==
    {|
    |-
    ! Before
    ! After
    |-
    | <code cppqt>
    int square(int n);
    </code>
    | <code cppqt>
    inline int square(int n) { return n * n; }
    </code>
    |-
    | <code cppqt>
    int square(int n) { return n * n; }
    </code>
    | <code cppqt>
    inline int square(int n) { return n * n; }
    </code>
    |-
    | <code cppqt>
    class Math
    {
        int square(int n);
    };
     
    // the following could be in a .cpp
    int Math::square(int n)
    { return n * n; }
    </code>
    | <code cppqt>
    class Math
    {
        int square(int n);
    };
     
    // the following could be in a .cpp
    inline int Math::square(int n)
    { return n * n; }
    </code>
    |-
    | <code cppqt>
    class Math
    {
        int square(int n);
    };
     
    // the following could be in a .cpp
    int Math::square(int n)
    { return n * n; }
    </code>
    | <code cppqt>
    class Math
    {
        int square(int n)
        { return n * n; }
    };
    </code>
    |}
     
    == Change the parameters of a function ==
    {|
    |-
    ! Before
    ! After
    |-
    | <code cppqt>
    void doSomething(int i1, int i2);
    </code>
    | <code cppqt>
    void doSomething(int i1, short i2);
    </code>
    |-
    | <code cppqt>
    void doSomething(int i1, int i2);
    </code>
    | <code cppqt>
    void doSomething(int i1, int i2, int i3 = 0);
    </code>
    |-
    | <code cppqt>
    void doSomething(int i1);
    </code>
    | <code cppqt>
    void doSomething(const int i1); // breaks with MSVC and Sun CC
    </code>
    |-
    | <code cppqt>
    void doSomething(char *ptr);
    </code>
    | <code cppqt>
    void doSomething(const char *ptr);
    </code>
    |}
     
    == Change the return type ==
    {|
    |-
    ! Before
    ! After
    |-
    | <code cppqt>
    QTcpSocket *createDevice();
    </code>
    | <code cppqt>
    QIODevice *createDevice();
    </code>
    |}
     
    == Change the access rights ==
    {|
    |-
    ! Before
    ! After
    |-
    | <code cppqt>
    class MyClass
    {
    protected:
        void doSomething();
    };
    </code>
    | <code cppqt>
    class MyClass
    {
    public:
        void doSomething();
    };
    </code>
    |}
     
    == Change the CV-qualifiers ==
    {|
    |-
    ! Before
    ! After
    |-
    | <code cppqt>
    class MyClass
    {
    public:
        int something() const;
    };
    </code>
    | <code cppqt>
    class MyClass
    {
    public:
        int something();
    };
    </code>
    |}
     
    == Add a virtual member function to a class without any ==
    {|
    |-
    ! Before
    ! After
    |-
    | <code cppqt>
    struct Data
    {
        int i;
    };
    </code>
    | <code cppqt>
    struct Data
    {
        int i;
        virtual int j();
    };
    </code>
    |}
     
    == Add new virtuals to a non-leaf class ==
    {|
    |-
    ! Before
    ! After
    |-
    | <code cppqt>
    class MyClass
    {
    public:
        virtual ~MyClass();
        virtual void foo();
    };
    </code>
    | <code cppqt>
    class MyClass
    {
    public:
        virtual ~MyClass();
        virtual void foo();
        virtual void bar();
    };
    </code>
    |}
     
    == Change the order of the declaration of virtual functions ==
    {|
    |-
    ! Before
    ! After
    |-
    | <code cppqt>
    class MyClass
    {
    public:
        virtual ~MyClass();
        virtual void foo();
        virtual void bar();
    };
    </code>
    | <code cppqt>
    class MyClass
    {
    public:
        virtual ~MyClass();
        virtual void bar();
        virtual void foo();
    };
    </code>
    |}
     
    == Override a virtual that doesn't come from a primary base ==
    <code cppqt>
    class PrimaryBase
    {
    public:
        virtual ~PrimaryBase();
        virtual void foo();
    };
     
    class SecondaryBase
    {
    public:
        virtual ~PrimaryBase();
        virtual void bar();
    };
    </code>
    {|
    |-
    ! Before
    ! After
    |-
    | <code cppqt>
    class MyClass: public PrimaryBase, public SecondaryBase
    {
    public:
        ~MyClass();
        void foo();
    };
    </code>
    | <code cppqt>
    class MyClass: public PrimaryBase, public SecondaryBase
    {
    public:
        ~MyClass();
        void foo();
        void bar();
    };
    </code>
    |}
     
    == Override a virtual with a covariant return with different top address ==
    <code cppqt>
    struct Data1 { int i; };
    class BaseClass
    {
    public:
        virtual Data1 *get();
    };
     
    struct Data0 { int i; };
    struct Complex1: Data0, Data1 { };
    struct Complex2: virtual Data1 { };
    </code>
    {|
    |-
    ! Before
    ! After
    |-
    | <code cppqt>
    class MyClass: public BaseClass
    {
    public:
    };
    </code>
    | <code cppqt>
    class MyClass: public BaseClass
    {
    public:
        Complex1 *get();
    };
    </code>
    |-
    | <code cppqt>
    class MyClass: public BaseClass
    {
    public:
    };
    </code>
    | <code cppqt>
    class MyClass: public BaseClass
    {
    public:
        Complex2 *get();
    };
    </code>
    |}

    Latest revision as of 18:25, 10 March 2016

    This page is now on the community wiki.