magic_numbers revision 9c3531d72aeaad6c5f01efe6a1c82023e1379e4d
9bff67898d55cddfcec9ce30cc2b1bb6211ec691David LawrenceCopyright (C) 1999, 2000 Internet Software Consortium.
9bff67898d55cddfcec9ce30cc2b1bb6211ec691David LawrenceSee COPYRIGHT in the source root or http://www.isc.org/copyright for terms.
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley
9c3531d72aeaad6c5f01efe6a1c82023e1379e4dDavid Lawrence$Id: magic_numbers,v 1.3 2000/06/22 21:54:04 tale Exp $
9c3531d72aeaad6c5f01efe6a1c82023e1379e4dDavid Lawrence
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob HalleyMagic Numbers
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob HalleyA number of data structures in the ISC and DNS libraries have an unsigned int
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halleymagic number as the first field. The purpose of the magic number is
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halleyprincipally to validate that a pointer a subroutine has gotten really points
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halleyto the type it claims to be. This helps detect problems caused by resources
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halleybeing freed prematurely, that have been corrupted, or that have not been
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halleyproperly initalized. It can also be handy in debugging.
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob HalleyMagic numbers should always be the first field. They never require locking
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halleyto access. As to the actual value to be used, something mnemonic is good:
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley #define TASK_MAGIC 0x5441534BU /* TASK. */
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley #define VALID_TASK(t) ((t) != NULL && \
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley (t)->magic == TASK_MAGIC)
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley #define TASK_MANAGER_MAGIC 0x54534B4DU /* TSKM. */
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley #define VALID_MANAGER(m) ((m) != NULL && \
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley (m)->magic ==
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley TASK_MANAGER_MAGIC)
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob HalleyUnless the memory cost is critical, most objects should have a magic number.
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob HalleyThe magic number should be the last field set in a creation routine, so that
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halleyan object will never be stamped with a magic number unless it is valid.
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob HalleyThe magic number should be set to zero immediately before the object is
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halleyfreed.
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob HalleyMagic values are generally private to the implementation of the type. I.e.
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halleythey are defined in the .c file, not the .h file.
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob HalleyValidation of magic numbers is done by routines that manipulate the type,
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halleynot by users of the type. Indeed, user validation is usually not possible
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halleybecause the magic number is not public.
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob HalleyMagic number checking may become a build option in a future release. E.g.
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley struct foo {
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley ISC_MAGIC_DECLARATION
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley /* ... */
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley }
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley foo_create() {
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley /* ... */
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley ISC_MAGIC_SET(value);
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley }
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley foo_destroy() {
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley /* ... */
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley ISC_MAGIC_CLEAR(value);
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley }
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley #define FOO_MAGIC 0x00010203U
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley #define VALID_FOO(f) ISC_MAGIC_VALIDATE(f, FOO_MAGIC)
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley foo_dosomething(foo *f) {
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley REQUIRE(VALID_FOO(f));
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley }