Re: Update needed to binary compatibility guide for Windows?
On Sunday 13 April 2014 23:15:30 Nicolás Alvarez wrote: 2014-04-13 22:36 GMT-03:00 Michael Pyne mp...@kde.org: Hi all, In the past couple of days our Binary Compatibility in C++ TechBase page [1] was posted to Reddit [2]. That post received a response [3] which indicated that we're actually missed a potential source of binary incompatibility with virtual functions on Windows with MSVC. Specifically, that adding an override of an existing virtual function in a class may cause other vtable function entries to be re-ordered. E.g. in something like: class blah { public: virtual void func1(int arg); virtual void func2(int arg); virtual void func3(int arg); }; Adding a virtual override func2(char *arg) to the *end* might cause the vftable to line up as if declared in this order: class blah { public: virtual void func1(int arg); virtual void func2(int arg); virtual void func2(char *arg); virtual void func3(int arg); // moved }; Is anyone able to confirm this behavior on Windows? If it's true, do we want to adopt a constraint on our handling of virtual functions in leaf classes based on this? (Adding virtual methods is already not permitted for non-leaf classes) I can confirm this behavior happens. I compiled this class: struct Testobj { virtual void func1(); virtual void func2(); virtual void func3(); }; And a program that calls func1(); func2(); func3(); Then I added a func2(int) overload to the *end*: struct Testobj { virtual void func1(); virtual void func2(); virtual void func3(); virtual void func2(int); }; and recompiled the class but not the program using the class. Output of calling func1(); func2(); func3(); was This is func1 This is func2 taking int This is func2 This shows that if I declare func1() func2() func3() func2(int), the vtable is laid out as func1() func2(int) func2() func3(). Tested with MSVC2010. Awesome, please add this information to the guide on the wiki. The page is a quite helpful one, i.e. no wonder it was posted to reddit. Having it as extensive as possible is a good thing imo. Cheers -- Milian Wolff m...@milianw.de http://milianw.de
Re: Update needed to binary compatibility guide for Windows?
On Mon, April 14, 2014 18:28:14 Ian Monroe wrote: On Sun, Apr 13, 2014 at 6:36 PM, Michael Pyne mp...@kde.org wrote: If it's true, do we want to adopt a constraint on our handling of virtual functions in leaf classes based on this? IMO we shouldn't worry about ABI on Windows. And not because meh Windows, but since Microsoft breaks C++ ABI with every compiler release, which is quite frequently these days. In general C++ ABI stability just isn't a thing on Windows. I've looked it up and you're right, they don't even pretend to try to maintain ABI compatibility (instead they recommend using an extern C wrapper or a COM interface). But at the same time we went through a time where GCC seemed to have to fix their C++ ABI every release and we tried to maintain the same binary compatibility standards throughout. I think what I'll do is note the issue. But in fact it may be worse: Do we require that applications never derive from our exported classes? I.e. do we export interfaces (which should not be derived from) or classes (which can be subclassed)? Because if we export classes with virtual methods, and then an application subclasses our class with their own virtual methods, then adding another virtual method to our most derived exported class would break the application even with the GCC ABI. Regards, - Michael Pyne
Re: Update needed to binary compatibility guide for Windows?
On Sun, Apr 13, 2014 at 6:36 PM, Michael Pyne mp...@kde.org wrote: If it's true, do we want to adopt a constraint on our handling of virtual functions in leaf classes based on this? IMO we shouldn't worry about ABI on Windows. And not because meh Windows, but since Microsoft breaks C++ ABI with every compiler release, which is quite frequently these days. In general C++ ABI stability just isn't a thing on Windows. And we are both the upstream and the downstream for the releases anyways. To that latter point, I guess really it matters what the KDE Windows team thinks. Ian
Re: Update needed to binary compatibility guide for Windows?
2014-04-13 22:36 GMT-03:00 Michael Pyne mp...@kde.org: Hi all, In the past couple of days our Binary Compatibility in C++ TechBase page [1] was posted to Reddit [2]. That post received a response [3] which indicated that we're actually missed a potential source of binary incompatibility with virtual functions on Windows with MSVC. Specifically, that adding an override of an existing virtual function in a class may cause other vtable function entries to be re-ordered. E.g. in something like: class blah { public: virtual void func1(int arg); virtual void func2(int arg); virtual void func3(int arg); }; Adding a virtual override func2(char *arg) to the *end* might cause the vftable to line up as if declared in this order: class blah { public: virtual void func1(int arg); virtual void func2(int arg); virtual void func2(char *arg); virtual void func3(int arg); // moved }; Is anyone able to confirm this behavior on Windows? If it's true, do we want to adopt a constraint on our handling of virtual functions in leaf classes based on this? (Adding virtual methods is already not permitted for non-leaf classes) I can confirm this behavior happens. I compiled this class: struct Testobj { virtual void func1(); virtual void func2(); virtual void func3(); }; And a program that calls func1(); func2(); func3(); Then I added a func2(int) overload to the *end*: struct Testobj { virtual void func1(); virtual void func2(); virtual void func3(); virtual void func2(int); }; and recompiled the class but not the program using the class. Output of calling func1(); func2(); func3(); was This is func1 This is func2 taking int This is func2 This shows that if I declare func1() func2() func3() func2(int), the vtable is laid out as func1() func2(int) func2() func3(). Tested with MSVC2010. -- Nicolás