|
Boost : |
From: David Abrahams (david.abrahams_at_[hidden])
Date: 2001-07-10 16:37:07
----- Original Message -----
From: "Beman Dawes" <bdawes_at_[hidden]>
To: "Boost.org mailing list" <boost_at_[hidden]>
> Sections 7.3 and 7.4 say:
>
> 7.3. All function interfaces must be commented (except for copy
> constructors, operator overloads such as copy-assignment and dereference,
> and destructors). The comment describes precisely what the function
> requires, what its effects are (especially including side-effects), and
> gives notice if the function provides anything other than the strong
> exception-safety guarantee. Accuracy is more important than brevity*.
>
> 7.4. Comment function interfaces in just one place. It can be difficult
> enough just to keep comments synchronized with code. Just as not
> duplicating code reduces the risk that some code will grow stale,
> commenting a function in one place only reduces the risk of comments not
> being maintained together. Whether a function interface comment must
appear
> at the point of declaration or of definition is covered below.
>
> I have several concerns with the above:
>
> * They fail to mention the case of functions which are documented
> externally, and thus should not be documented via comments in the code.
Agreed. These guidelines were not written for code with supporting HTML docs
like we have at boost. They should be modified accordingly.
> * A function documentation form which more closely follows the C++
standard
> should be encouraged, IMO. The standard form is familiar and will ease
the
> transition from Boost documentation to formal standard, should the
function
> become part of the standard.
In principle, yes.
> * Particularly for small, simple functions which are part of the
> implementation (and thus not part of the published interface), inline
> implementation is often the simplest and clearest way to document a
> function.
I don't think I agree here. Even internal functions which are not part of
the public interface are part of the private interface. I don't think an
inline implementation documents anything except an implementation. Every
function deserves documentation, and code is almost never a substitute. A
comment allows you to test a function, or to change its implementation, and
to know what you're aiming for.
> Here is a reformulation:
>
> 7.3 All function interfaces must be documented, except for functions with
> obvious semantics, such copy constructors, operator overloads such as
> copy-assignment and dereference, and destructors. Even these functions
must
> be documented if their semantics are in any way unusual.
OK.
> 7.4 Document function interfaces in just one place. It can be difficult
> enough just to keep documentation synchronized with code. Just as not
> duplicating code reduces the risk that some code will grow stale,
> documenting a function in one place only reduces the risk of the
> documentation being maintained inconsistently.
>
> 7.4+ Document functions in an appropriate format:
>
> * Functions which are part of a library's public interface should be
> documented in the project's preferred external document format. (For
Boost,
> that's HTML.) For functions documented externally, the code should include
> a comment (possibly given once a the beginning of the header file)
pointing
> to the appropriate documentation. As more and more program editors
> recognize URL's in comments, it makes sense for the pointer to be a valid
> URL.
OK
> * Functions interfaces not documented externally (presumably because they
> are implementation helpers not part of the published interface) are
> documented by program comment, which must appear at the point of
> declaration or of definition as described below.
I guess as metaprograms become more common we should say something to cover
the equivalent implementation-detail class templates.
> *Inline implementation of implementation helper functions may serve as
> documentation, provided the implementation is very short, simple, and has
> the net effect of making program meaning easier to understand.
I'm quite reluctant about that one, as I've said.
> 7.4++ Document functions in standard form. The elements of standard form
> function documentation (ISO 17.3.1.3) are given below. (Rationale is an
> addition to the standard form.) Elements which do not apply should be
> omitted. Accuracy is more important than brevity*.
>
> Signature(s) of the function(s) to be documented, follow by:
>
> * Requires: the preconditions for calling the function, such as valid
> values for arguments.
>
> * Effects: the actions performed by the function, especially side-effects.
> Postconditions: the observable results established by the function.
The issue of side-effects gets very interesting. I've recently been emailing
with Scott Meyers who is having a hard time putting the effects of functions
(say, those giving the strong exception-safety guarantee) in simple and
precise terms. I don't blame him. The difficulty occurs when a function
calls back into client code (e.g. when the client supplies a template
parameter, a derived class instance overriding a virtual function, or a
function pointer). To be really precise about this, you have to specify the
assumptions that the library makes about which client operations undo which
other ones (e.g. construction <=> destruction).
> * Returns: a description of the value(s) returned by the function.
>
> * Throws: identifies any exceptions thrown by the function, and the
> conditions that would cause the exception.
Here again it gets kind of interesting, since client code called by the
library can throw exceptions. Since most of our code is probably
exception-neutral, we will want a blanket statement somewhere that client
code is allowed (unless otherwise specified) to throw anything and that we
will pass the exception to the library's caller.
> Also gives notice if the
> function provides anything other than the strong exception-safety
> guarantee.
I could have sworn I changed that! I strongly believe the default guarantee
should be the basic guarantee.
> * Complexity: the time and/or space complexity of the function.
I think there are domains in which this may be irrelevant, or left as QOI.
For example, we don't document the complexity of the iostreams operations in
the standard. It might be too burdensome to ask the author of... oh, just
for instance, the Python library (!) to document the complexity of functions
which are expected to have a huge constant factor anyway.
> * Rationale: a description of why the function is or isn't designed in a
> certain way. For example, why an argument or return value of a type
> normally passed by reference is passed by value (or visa versa).
Rationale is good.
-Dave
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk