12

Does changing the order of public non-virtual non-inline overloaded methods in a stand-alone class break the ABI?

Before:

class MyFinalClass
{
public:
    // ...
    void doSomething(char c, int i, int n);
    void doSomething(char c, int i);
    // ...
};

After:

class MyFinalClass
{
public:
    // ...
    void doSomething(char c, int i);
    void doSomething(char c, int i, int n);
    // ...
};

Thanks!

linuxbuild
  • 15,843
  • 6
  • 60
  • 87
Víctor Fernández
  • 1,754
  • 1
  • 16
  • 15
  • 2
    In theory the answer depends on which platform/toolchain you're using - C++ mandates no specific ABI. – Flexo May 10 '12 at 15:13
  • 4
    For those like me who didn't knew what ABI means: http://en.wikipedia.org/wiki/Application_binary_interface Now you do! – Stormenet May 10 '12 at 15:14

2 Answers2

12

The functions are linked by their name and signature, not by their position in the class. So no, you're not breaking the ABI.

Virtual functions are a different matter because they're linked by their position in a vtable (usually). This won't be a problem if you consistently recompile every file that depends on the header that defines the order, but if the class exists in a library it could be a concern.

Mark Ransom
  • 299,747
  • 42
  • 398
  • 622
1

There are two things that breaks the ABI when you update your classes. Virtual functions as pointed out by Mark (and remember that it is not because you did not mark a function as virtual that it isn't.)

The other things are inline functions because those make use of your variable members. If the order of your variable members changes then those inline's that were compiled in other software break too.

As pointed out by Russel Greene (see comment) the order of variable members can also cause alignment differences which is enough to change the size of the allocated objects. That also breaks your allocation (assuming the client's code uses new)

And adding/removing members may not break the ABI (you still could allocate a byte here or a word there...) but that's usually a deal breaker right there.

Alexis Wilke
  • 19,179
  • 10
  • 84
  • 156
  • 2
    Since the question didn't mention reordering member variables I didn't consider it in my answer, very good point! They don't even have to be public. Also I appreciate your reminder that a base class can make a function virtual even if it isn't declared so in a derived class. – Mark Ransom May 10 '12 at 15:59
  • 2
    Order of member variables is actually more consequential than just breaking inline functions--it can change the size of the structure (due to alignment), which can cause memory corruption. See http://cpp.sh/4ynmj – Russell Greene Jul 30 '19 at 14:24