magic_numbers revision 816e576f77e2c46df3e3d97d65822aa8aded7c4b
0N/ACopyright (C) 1999, 2000 Internet Software Consortium.
2362N/ASee COPYRIGHT in the source root or http://isc.org/copyright.html for terms.
0N/A
0N/A$Id: magic_numbers,v 1.4 2000/08/09 04:37:33 tale Exp $
0N/A
0N/AMagic Numbers
2362N/A
0N/AA number of data structures in the ISC and DNS libraries have an unsigned int
2362N/Amagic number as the first field. The purpose of the magic number is
0N/Aprincipally to validate that a pointer a subroutine has gotten really points
0N/Ato the type it claims to be. This helps detect problems caused by resources
0N/Abeing freed prematurely, that have been corrupted, or that have not been
0N/Aproperly initalized. It can also be handy in debugging.
0N/A
0N/AMagic numbers should always be the first field. They never require locking
0N/Ato access. As to the actual value to be used, something mnemonic is good:
0N/A
0N/A #define TASK_MAGIC 0x5441534BU /* TASK. */
0N/A #define VALID_TASK(t) ((t) != NULL && \
0N/A (t)->magic == TASK_MAGIC)
2362N/A
2362N/A #define TASK_MANAGER_MAGIC 0x54534B4DU /* TSKM. */
2362N/A #define VALID_MANAGER(m) ((m) != NULL && \
0N/A (m)->magic ==
0N/A TASK_MANAGER_MAGIC)
0N/A
0N/AUnless the memory cost is critical, most objects should have a magic number.
0N/A
0N/AThe magic number should be the last field set in a creation routine, so that
0N/Aan object will never be stamped with a magic number unless it is valid.
0N/A
0N/AThe magic number should be set to zero immediately before the object is
0N/Afreed.
0N/A
0N/AMagic values are generally private to the implementation of the type. I.e.
0N/Athey are defined in the .c file, not the .h file.
0N/A
0N/AValidation of magic numbers is done by routines that manipulate the type,
0N/Anot by users of the type. Indeed, user validation is usually not possible
0N/Abecause the magic number is not public.
0N/A
0N/AMagic number checking may become a build option in a future release. E.g.
0N/A
0N/A struct foo {
0N/A ISC_MAGIC_DECLARATION
0N/A /* ... */
0N/A }
0N/A
0N/A foo_create() {
0N/A /* ... */
0N/A ISC_MAGIC_SET(value);
0N/A }
0N/A
0N/A foo_destroy() {
0N/A /* ... */
0N/A ISC_MAGIC_CLEAR(value);
0N/A }
0N/A
0N/A #define FOO_MAGIC 0x00010203U
0N/A #define VALID_FOO(f) ISC_MAGIC_VALIDATE(f, FOO_MAGIC)
0N/A
0N/A foo_dosomething(foo *f) {
0N/A REQUIRE(VALID_FOO(f));
0N/A }
0N/A