The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.
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();
};
|