[Date Prev][Date Next][Thread Prev][Thread Next][Author Index][Date Index][Thread Index]

Re: easy to miss bug (even in structured debug)



Abstract:
 - I agree that forbidding NULL if nothing is said about it is a
   good idea.  Let's do it.
 - Subcontracting assurance of valid argument values is not an
   error (though it is sometimes unwise).
 - NULL-where-pointer-is-expected should be replaced by separate
   routines unless it's the logical result of reaching a
   data-structure boundary.

> From mark Sat Dec  2 19:34:06 1989
> 
> 1) An expression of type "Foo *" may NOT have the value NULL unless
> this possibility is explicitly notated, either with an explicit
> comment or by one of the following conventions.  Note that this
> convention is the opposite of Michael's suggestion that a "Foo *" may
> be NULL unless the contract guarantees that it cannot.  Were we
> programming in the C style of NULL use (i.e., without BLAST),
> Michael's suggestion would be right.  However, in our style the
> NULL-allowed case is quite rare, and therefore the other default
> assumption makes sense.

OOPS!  I reviewed my letter, and it can be read that NULL is allowed
by default.  What I meant to say is that the interface must be
documented, and it must be clear from the documentation what values
are allowed or forbidden.  That means if there is special behavior
when NULL is passed, that must be called out as well.

But cases where the behavoir for a NULL argument is obvious are
rare.  (In our style, they're even rarer than usual.)  I agree
that forbidding NULL as a pointer-argument value unless allowing
it is documented is the proper standard.

By the way, a major point I was trying to make in my letter was that
when a caller violates a routine's contract, it is NOT an error for
that routine to violate the contracts of routines IT calls.  It is
proper structured-debug form to subcontract incoing-part inspection
to the supplying department.  (Nevertheless, it is wise to do redundant
contract-compliance inspection at programmer responsibility and major
package boundaries, and it's necessary at server/client boundaries,
such as FEBE.)

> 3) Any function parameter that may be passed a NULL be declared with
> NULL as its default value.  This is intuitively sensible as NULL can
> then be read as indicating the lack of an argument in that position.

Can this be done in a middle argument?

By the way:  One of the things structured-programming tries to
eliminate is "switched" routines - routines which do two or more
distinct (but conceptually-related) jobs depending on one or more
switch arguments.

It strikes me that a NULL where a pointer is expected (if it isn't
the logical result of reaching a boundary in a data structure) is
doing the job of a switch.  In these cases, the KISS principle says
to write separate routines.  Since c++ supports overloading and
default arguments, that shouldn't be a burden.

	michael