John Sonnenschein wrote:
> I may regret throwing my hat in to this ring in the future, but with 
> respect to the example about user downloading $APP and having it not 
> work because it uses $FOO ( linked to libCstd ) and $BAR ( linked to 
> stdcxx ), that would mean that the developer of $APP explicitly linked 
> to both, which is just silly, that $FOO or $BAR changed under it's 
> feet, which would be a different ARC case altogether,  or that 
> $FOO/$BAR had the STL ripped out from under /it's/ feet, and removal 
> of old libraries would be yet another ARC case altogether.

No, the problem is that because they were linked with different 
implementations of the C++ standard library, $FOO and $BAR cannot 
coexist in the same address space.

    -- Garrett
>
> Take care
> -John
>
> On 5-Sep-08, at 4:46 PM, Garrett D'Amore wrote:
>
>> Thank you for your instructional description of the C++ language with
>> respect to templates.
>>
>> There are a few significant points, that I think you keep missing, or
>> are glossing over:
>>
>> When I said C++ doesn't separate *binary* interface from implementation,
>> I was *not* talking about the nice separation done for the benefit of
>> the programmer.  I was talking about separation done across the boundary
>> created by the linker ... AFAIK, C++ does not recognize that there is
>> such an interface boundary.
>>
>> In C++, if an inline function is expanded by the compiler, but makes use
>> of *private* members of the class, then the *binary implementation* of
>> the resulting code is *tied* to the implementation, and if the
>> implementation changes (e.g. by changing the dynamically linked library)
>> then there can be unfortunate consequences.
>>
>> I'm not a template expert, so I'll demonstrate with a simple inline
>> function using C++ circa 1990.
>>
>> class box {
>>    int      width;
>>    int      height;
>>    /* put more private details here... */
>>
>>   public:
>>       void draw();   // private implementation elsewhere
>>
>>   public inline int getwidth() { return width; }
>> };
>>
>> If this is in header, then the implementation parts (the width, the
>> height and their offsets within the class) wind up getting encoded into
>> the binary that includes this header.  If the width or the height ever
>> move (e..g by moving another member in front of them in the class), then
>> the binary is busted.  Likewise, if the private members change type
>> (e.g. from a uint16_t to a uint32_t), breakage ensues.
>>
>> It is possible to have implementations that don't suffer from this
>> problem, but it requires that the implementation refrain from inline
>> functions, and take care that the headers *only* expose portions of the
>> classes that will never ever change (or change in a way that breaks the
>> binary implementation of the class.)  I won't endeavor to describe how
>> this problem may or may not affect templates, as such is out of my area
>> of expertise.
>>
>> I've not kept up with the C++ standards admittedly, but I believe that
>> this aspect of binary compatibility is not one that has been addressed
>> in the standards, and likely not in the specification of the libraries.
>> It is possible that the Apache product has taken great care to avoid
>> this kind of potential breakage, but my first reaction is doubt.
>>
>> Now, that's only *one* aspect of the "compatibility problem."
>>
>> There is a grave and other serious problem, which relates to the fact
>> that this proposal effectively creates a new baseline (i.e. a new ABI)
>> for C++ programs, where programs linked (directly or indirectly) against
>> this library are incompatible with our one and only bless (at this time)
>> ABI, based on the libC that ships with Solaris today.
>>
>> And, the project recognizes that future breakage is not just possible,
>> but *likely*, when either the compiler team ships another project, or
>> when the library needs an update due to changes in the standard.
>>
>> Imagine the plight of the poor user who downloads a program
>> (WhizzyDownloadTracker) which uses two different class libraries.  On
>> the one hand, it uses the NiftyNetworking library for networking
>> functionality, and it uses the KDE libraries for user interface work.
>> Well, good thing, the IPS repo contains both NiftyNetworking and KDE.
>> Download both, install, and then download, compile (via ./configure) and
>> install the WhizzyDownloadTracker.  All's good, right?
>>
>> Well, a few hours later, when the compile for WhizzyDownloadTracker
>> finally completes, we find out life isn't so good.
>>
>> Because you see, the NiftyNetworking set was not built with the Apache
>> libstdc++, but instead with the "default" libraries that we have been
>> recommending people use for years.  The user tries to run the program,
>> and if he's lucky, gets a meaningful link error message.  In reality,
>> the error message, if any, that results is probably completely cryptic
>> to the end user, who was just trying to install software.  In a worse
>> scenario, the program just dumps core mysteriously.
>>
>> The worst part of the above scenario, apart from the confusion that the
>> poor non-C++-developing victim gets to experience, is that he's
>> downloaded the foundation libraries from a single source (Sun's IPS
>> repo), so they *should* work together, shouldn't they?!?
>>
>> Too bad.
>>
>> So now the user complains to the FOSS authors for WhizzyDownloadTracker,
>> who are unfamiliar with Solaris (they did their development on Linux,
>> see?), and don't know that Solaris has multiple incompatible C++ ABIs,
>> nor how to tell which components were built against which ABI.
>>
>> So, the FOSS author probably gives up, and tells the poor user that he
>> needs to recompile the base libraries (either KDE or NiftyNetworking),
>> so that they are built with compatible libraries.
>>
>> At this point, the FOSS author is laughing at Sun and Solaris, and
>> probably also cheerfully writes a blog somewhere admonishing folks
>> against running Solaris.
>>
>> And, the original user?  He's probably given up.  Most likely he either
>> he chooses not to use WhizzyDownloadTracker, or winds up giving up on
>> Solaris and switches back to Linux or Windows.  Either way he's probably
>> pretty ticked that "Sun" is delivering crapware that just doesn't work
>> together.
>>
>> I don't know if the above illustration clearly enough paints the picture
>> of my features, but I think it certainly demonstrates that we cannot
>> just blithely ignore the issue and pretend it won't affect anyone.
>>
>>    -- Garrett
>>
>> Stefan Teleman wrote:
>>>
>>>
>>> Garrett D'Amore wrote:
>>>> John Plocher wrote:
>>>>> Garrett D'Amore wrote:
>>>>>> One of the implications of such a binding (Volatile), is that
>>>>>> projects which build other C++ shared libraries upon this one
>>>>>> cannot have a commitment level higher than Volatile either.
>>>>>
>>>>> Braap.  Bad Architecture Alert.  The whole reason we provide
>>>>> abstractions
>>>>> like consolidations and components is precisely so that we can 
>>>>> provide
>>>>> "higher than Volatile" expectations for things that theselves may
>>>>> exhibit
>>>>> "less than Volatile" stability.
>>>>>
>>>>> There is no reason this couldn't be made a part of the KDE
>>>>> consolidation,
>>>>> and maintained by them as Committed interfaces for use by any KDE
>>>>> consumers
>>>>> who need it.  Volatile means "can change", not "will change", and
>>>>> both the
>>>>> Apache C++ Lib and the KDE projects certainly seem to meet the basic
>>>>> ARC
>>>>> expectations of managing the compatible evolution of their component.
>>>>>
>>>>> If the C++ basis that KDE builds upon were to change incompatibly, 
>>>>> I'd
>>>>> expect KDE to react by producing a major release - again, just 
>>>>> like the
>>>>> ARC would expect.
>>>>>
>>>>> Nothing here requires KDE to be Volatile.
>>>>
>>>> We're not talking about something that is delivered with
>>>> Consolidation Private binding... we're talking about (assuming
>>>> Volatile binding) something that could change underneath KDE.  Such a
>>>> change would be devastating to binary compatibility for applications
>>>> linking against KDE C++ libraries.
>>>>
>>>> If KDE has a way to shield applications underneath from such a binary
>>>> breakage, then its a different story altogether.  However, my
>>>> understanding is that in this case (unlike more simple cases
>>>> involving only C), there isn't a way for KDE to do that.
>>>
>>> This ARC Case is not about KDE, but about the Standard C++ Library.
>>> What KDE may or may not expose in its header files, and how it handles
>>> implementation delegation design patterns is for a different ARC Case.
>>>
>>>> I.e. with C++ code, if application #include's a KDE header, which
>>>> itself #include's a libstdc++ header,  the binary bits of the
>>>> application *very* likely contain details of the underlying libstdc++
>>>> implementation encoded in them.
>>>
>>> It is the responsibility of the implementation to shield any private
>>> and potentially incompatible implementation details from the publicly
>>> exported interfaces. For the purposes of this statement, "interfaces"
>>> refers to both source and binary.
>>>
>>> The principle of separating interface from implementation is one of
>>> the Design Principles of the C++ Programming Language, and has been a
>>> C++ software design principle ever since the creation of the Language.
>>> It has been widely discussed and documented in relevant literature,
>>> and it has also been put in practice by many C++ software systems,
>>> including, but not limited to, the Apache Standard C++ Library, and/or
>>> the existing libCstd.so.1.
>>>
>>>> C++ is reasonably good at providing good programmatic boundaries
>>>> between interface and implementation at the *source* code level.
>>>> However, it falls down completely at the *binary* level.  (Which
>>>> isn't to say that libraries simply *can't* prevent this sort of
>>>> problem -- merely that the expectation should *not* be that they do,
>>>> because it will probably require some rather grotesque contortions on
>>>> the part of the library to do so.)
>>>
>>> The private implementation details of any particular C++ software
>>> system are just that: private. The blanket statement that C++ falls
>>> down completely at the binary compatibility level is false, and it is
>>> invalidated by existing software practice. It is indeed possible to
>>> maintain binary compatibility for a C++ software system, and no
>>> grotesque contortions are required to achieve this goal.
>>>
>>>> Now, if the library (KDE) never #include's "standard" C++ headers
>>>> (provided by this library) in its own headers (that it exports to
>>>> applications), but only uses them in .cxx (or .cpp or .C or whatever)
>>>> implementation files, then I agree that there is no problem.
>>>> (Although the consuming application may itself still wind up needing
>>>> to have its own dependency upon the libstdc++, but that issue is
>>>> largely orthogonal as far as something like KDE is concerned.)
>>>
>>> The dependency constraint has already been clearly stated in the ARC
>>> Case.
>>>
>>> Although it is generally considered a poor software implementation
>>> choice to #include Standard C++ Library header files in application
>>> header files exporting public interfaces, the implementation of the
>>> Apache Standard C++ Library allows for this inclusion, without
>>> breaking ABI [ pursuant to the compatibility constraints described in
>>> the ARC Case Materials ]. However, the Language allows for the
>>> implicit inclusion of interfaces from the Standard C++ Library [ or
>>> for that matter, any other library ], in header files, without the
>>> need for explicit #include directives.
>>>
>>> The Library incompatibility constraint is still in effect: the Apache
>>> Standard C++ Library is not compatible with:
>>>
>>> - any implementation of the Apache Standard C++ Library, which is not
>>> at Major Release 4 level
>>> -  any _other_ implementation of the Standard C++ Library, including,
>>> but not limited to: libCstd.so, the GNU Standard C++ Library, STLport,
>>> etc.
>>>
>>>> To put this in comparison, imagine if almost all of the standard C
>>>> functions were simply *macros* rather than functions, and the macros
>>>> made references to volatile innards of the C library.  While the
>>>> *API* might be "clean" and safe, the *ABI* would most certainly not
>>>> be.  This is the situation that we're in with C++, I think.
>>>
>>> Intentionally, and by Language Design, C++ inline functions, or
>>> templates (which is what you are referring to) are *NOT* C macros. C++
>>> inline functions are functions. C++ templates are templates. Their
>>> symbols are mangled, they obey all the language overloading rules,
>>> they are assigned the implicit "this" pointer by the compiler (if they
>>> are class members), and they behave exactly in the same way as any
>>> other C++ function. They [ classes ] also implement a distinct type.
>>>
>>> The complexity of the implementation of C++ functions increases in the
>>> case where the class, or function in question, is a template (which is
>>> the case with the majority of the classes in the Standard C++
>>> Library). If the class is a template, the compiler instantiates a
>>> distinct type, based on the type defined by the class template itself,
>>> and on the underlying type upon which the template class is
>>> instantiated. This instantiation mechanism alone is fundamentally
>>> different than that of C macros.
>>>
>>> The type instantiation mechanism applies to non-template functions and
>>> classes as well.
>>>
>>> The compiler may or may not decide to eliminate the function call
>>> altogether, by inlining in the resulting object file, and this is a
>>> private decision of the compiler. The compiler may or may not decide
>>> to eliminate the instantiation of the template [ class or function ]
>>> altogether, based on internal compiler heuristic rules, and/or based
>>> on whether or not the actual template function or template class is
>>> actually referenced in the translation unit [ the default compiler
>>> decision can be overridden with specific compiler flags, but that
>>> facility is besides the point for this discussion ]. This decision,
>>> again, is a private decision of the compiler.
>>>
>>> At this point, your comparison with C macros has fundamentally broken
>>> down: there is no guarantee whatsoever that any of the template
>>> classes or functions, whose interfaces have been imported by the
>>> translation unit via header files, would have actually created the
>>> required type and its corresponding instance, and/or that the compiler
>>> has, in fact, generated the corresponding symbol(s) in the binary 
>>> object.
>>>
>>> The means by which the implementation achieves the asserted ABI
>>> compatibility goal is private to the implementation itself. In this
>>> particular case, under discussion, this compatibility is enforced by
>>> function calls to private, internal implementations of the facilities
>>> required by the Language Standard (hence the presence of the shared
>>> library object).
>>>
>>> Attempting to invalidate the ABI compatibility assertion of the
>>> implementation by drawing comparisons with C Language macros, or with
>>> the C Programming Language in general, is based on incorrect
>>> assumptions about the C++ Programming Language, and is bound to fail
>>> scrutiny.
>>>
>>> I am hereby requesting that the PSARC member who has derailed this
>>> case provides concrete proof of ABI breakage in the Apache Standard
>>> C++ Library, to the PSARC Committee, for review. Concrete proof means:
>>> source code, accompanied by an explanation of the breakage.
>>>
>>> For The Record: KDE has no intention whatsoever to modify the Standard
>>> C++ Library in an incompatible way.
>>>
>>> Thank you.
>>>
>>> --Stefan
>>>
>>
>> _______________________________________________
>> opensolaris-arc mailing list
>> opensolaris-arc at opensolaris.org
>


Reply via email to