
"David B. Held" <dheld@codelogicconsulting.com> writes:
David Abrahams wrote:
And yet, the question is how much of a library's implementation should be exposed/documented so that the user knows what they are affecting when they make globally intrusive changes? I'm not suggesting that a library should be responsible for things outside of its control. I'm saying that we have an issue of unavoidable coupling between the facilities a library uses and facilities that a user can customize, and the question becomes how much a library should expose that coupling to make users aware of the effects of customization. To pick an example, I sometimes see people complaining about whether or not some library uses standard allocators or not. In practice, one can customize allocation behavior by replacing the global operator new. But this is an intrusive customization which gives no guarantees to the user. For all the user knows, some implementations of a given library do not call operator new at all, but rather use an internal allocator with placement new. Should those facts be exposed to the user or not? The initial uses of a library would suggest not. You are arguing that as little detail as possible should be specified for a library.
Not exactly.
There is certainly merit in keeping things as simple as possible and not over-constraining implementors.
It's not about freedom for implementors. It's about understandability for users.
But I'm saying that people can, will, and are customizing anyway, sometimes in ways not initially expected by the authors of a given library. So I don't see the issue of how much detail to expose as an open-and-shut case. It seems to me that the progression is towards customization; and that means exposing more implementation policies and details, so that when a user does customize something not originally anticipated by a library author, at least the user knows what to expect. And if a library is documented to be implemented in a certain way, then the user even gets some guarantees they otherwise would not get if the implementation were completely undocumented.
I understand what you're saying, but I think it's really a different issue from the one we're discussing. At issue is this question: Is it OK to say that an operation that uses some user-customizable functionality preserves all invariants in the face of an exception? You are saying, IIUC, "yes, if either a.) the only possibility of an exception arises before a user-customizable function is ever invoked, or b.) we also say that the user-customizable function is pure" I am saying that case a. is very rare, in part because it also requires that the customization is prohibited from throwing. If case a. arises I'd prefer to say something like "if an exception is thrown the customization is never invoked". I'm also saying that in case b. the requirement on the purity of the function is "intuitively obvious": clearly if my customization twiddles some bits that the operation has no knowledge of, the operation can't untwiddle them. So I prefer not to belabor that point. Really, the question at issue is "what conventions will we adopt for documenting exception safety?" I prefer conventions that will describe the 99% cases in a few understandable words, and that require more language for the other 1%. We have the freedom to invent our own jargon/terminology/colloquialisms to accomplish that. If it means that we need a few paragraphs of documentation for people to understand how to read the specifications, I think that's preferable. -- Dave Abrahams Boost Consulting http://www.boost-consulting.com