Reading the Apache C++ sources (which I didn't want to do, but here you go), I ran into the following example snippet in the include directory (the include file is <streambuf>):
template<class _CharT, class _Traits> inline typename basic_streambuf<_CharT, _Traits>::int_type basic_streambuf<_CharT, _Traits>:: sputbackc (char_type __c) { _RWSTD_ASSERT (_C_is_valid ()); if (_C_putback_avail () && traits_type::eq (*(gptr () - 1), __c)) return traits_type::to_int_type (*--_C_gptr); return pbackfail (traits_type::to_int_type (__c)); } In the above example, the inline function has in it bits which appear to me to be implementation details (_C_putback_avail() is protected for example -- I'm not sure whether the *standard* specifies that it exist or not. _C_gptr is certainly a private member of the class, and I "presume" that the standard doesn't specify it, though I've not checked the standard since I don't have a copy of it handy.) The concern here is what happens if those portions of the implementation need to change? (What happens if _C_gptr moves in the class, or the implementation needs to change in a way that _C_gptr doesn't exist at all, or changes type? Bad things, I suspect.) Will the implementation take care to preserve the *existing* functions so that the above inline (which will now have been compiled into various applications) will continue to function, regardless of what other changes may be necessary for the class? I apologize for my apparently childish C++ example earlier -- as I said, I don't work in the language very often. But I *think* I've found a real example from Apache C++ that suffers the same problem. Do you disagree? -- Garrett Garrett D'Amore wrote: > Stefan Teleman wrote: >> >> >> 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; } >>> }; >> >> This is a hypothetical example of a very poorly designed C++ class. I >> would expect to see this type of design from a High School Student, >> and not from a professional. Certainly not from an industry leader. >> >> The quality of this implementation aside, this code excerpt is not >> from the Apache Standard C++ Library. >> >> Could you kindly provide an example of ABI breakage -- any kind of >> breakage -- from the source code of the Apache Standard C++ Library, >> currently under discussion ? >> >> Incidentally, the problem you are illustrating in your example has >> been solved about 14 years ago (if not earlier): >> >> http://www.amazon.com/Design-Patterns-Object-Oriented-Addison-Wesley-Professional/dp/0201633612/ref=sr_1_1?ie=UTF8&s=books&qid=1220661045&sr=1-1 >> >> >> >> Published November 10, 1994. >> >> As to which of the Design Patterns addresses this very exact problem >> is left as an exercise for the reader. > > Okay, I'm not interested in debating this further ... or even > researching it. I frankly don't have the energy to read the source > code for a significant library written in a language I don't work in > on a day to day basis. > > However, if you will assert that there are no binary compatibility > problems of this nature (nor any others of a similar nature arising > from templates) -- i.e. that the header files do not create a problem, > then I don't have a problem. > > The litmus test for this problem would be to take an application > compiled against one version the library, and replace the library > underneath it with a different implementation. If the applications > still work, then I'm satisfied. If the applications do not work, then > we have to make some kind of continuity statements or guarantees about > how we manage fixes and upgrades to the library. If Apache's > implementation guarantees that this breakage doesn't occur on minor or > patch upgrades, then that might be acceptable, although we have to > figure out continuity to ensure that the library (or a drop in > compatible replacement) will remain available for quite some time. > (Standard commitment effectively means ~forever, btw.) > > That still doesn't address the other major set of concerns I had, > about mixing and matching different implementations of the standard > libraries. I think I'm unhappy with anything above Volatile > commitment without a game plan that ultimately addresses the problem > and gets us to a single "recommended" base library implementation. > > -- Garrett >> >> --Stefan >> >