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.