Re: Update needed to binary compatibility guide for Windows?

2014-04-15 Thread Milian Wolff
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?

2014-04-15 Thread Michael Pyne
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?

2014-04-14 Thread Ian Monroe
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 Thread Nicolás Alvarez
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