On 05/21/12 07:00, Albrecht Schlosser wrote:
> On 17.05.2012 01:19, fltk-dev@easysw.com wrote:
>> Author: greg.ercolano
>> Date: 2012-05-16 16:19:37 -0700 (Wed, 16 May 2012)
>> New Revision: 9510
>> Log:
>> Added three methods and dox to Fl_Tooltip:
>>
>>      margin_width()  -- controls margins around tooltip's text
>>      margin_height() -- controls margins above and below tooltip's text
>>      wrap_width()    -- controls maximum width of text before wordwrapping 
>> is enforced
>>
>> These are read-only for the current release,
>> and read/write as an ABI feature.
> 
> Greg, on the first glance these methods all seem to be static, and
> according to [1] adding static data members to a class wouldn't
> break the ABI (adding static methods shouldn't either, IMHO).
> 
> If that's true, we could probably drop the ABI feature macro and
> make all new methods available...
> 
> Thoughts?

        Yes; it's probably true.

        I was thinking about that as I was developing, but noticed
        Fl_Tooltip was one of those classes that's referenced by
        'lower level' classes (Fl, Fl_mac, Fl_win32, Fl_Widget, etc.)
        so I wasn't sure if there might be some code elsewhere in FLTK
        that might somehow cause trouble.

        The thing that scares me the most is code changes made to
        both .H and .cxx files that depend on each other to work
        properly. This can cause trouble in DLL scenarios where
        the app compiled against an old .H file that contains logic
        incompatible with the new logic implemented in the newer .H/.cxx
        files of the lib, causing a negative reaction at runtime (**).

        This kind of thing doesn't seem to break any rules of the ABI,
        but actually does end up breaking the app.

        Seeing as how Fl_Tooltip spans all widgets, I thought I'd err
        on the safe side, and implement it as an ABI feature. I tagged it
        in my mind to follow up with an investigation into Fl_Tooltip's
        use throughout the lib to check for low level problems,
        but didn't get to that check because the changes ended up
        being reduced to very simple changes.


** Not sure if this is a good example, but here's what I mean,
   as it was a situation like this that leveraged me into coming up
   with ABI feature macro as a workaround.

   In the following, the changes would /appear/ not to break ABI rules,
   but still kinda does.

   If an app were built against 1.0, it'd run fine with a 1.0 DLL,
   but would crash with a div zero if runtime linked with a *1.1* DLL:

--- VERSION 1.0 --------------------
// MyClass.H
class MyClass {
    int div;
public:
    MyClass() { div = 1; }
    int Dimension(int val);
};

// MyClass.cxx
#include "MyClass.H"
int MyClass::Dimension(int val) {
    return(val/div);
}

--- VERSION 1.1 --------------------
// MyClass.H
class MyClass {
    int div;
    int Dimension(int val);
public:
    MyClass() { div = 0; }             // CHANGE
};

// MyClass.cxx
#include "MyClass.H"
int MyClass::Dimension(int val) {
    return (div==0) ? val : val/div;   // CHANGE
}

        Perhaps the definition of this isn't 'breaking ABI' so much
        as 'writing bad code', but if this were buried in more complex
        changes, it'd be easy to miss.

        If the constructor had been declared in the .cxx file
        instead of as an inline, there'd be no trouble.

        So it's not so much the code is 'bad', just that because
        the logic crosses .H and .cxx, it can cause trouble for DLL's.

_______________________________________________
fltk-dev mailing list
fltk-dev@easysw.com
http://lists.easysw.com/mailman/listinfo/fltk-dev

Reply via email to