magic_numbers revision 499b34cea04a46823d003d4c0520c8b03e8513cb
217f572018871cdf09db052a676b9933512cdbfaMark AndrewsCopyright (C) 1999-2001 Internet Software Consortium.
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark AndrewsSee COPYRIGHT in the source root or http://isc.org/copyright.html for terms.
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews$Id: magic_numbers,v 1.5 2001/01/09 21:47:01 bwelling Exp $
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark AndrewsMagic Numbers
217f572018871cdf09db052a676b9933512cdbfaMark Andrews
217f572018871cdf09db052a676b9933512cdbfaMark AndrewsA number of data structures in the ISC and DNS libraries have an unsigned int
4be63b1fd8c18dbeca1648d6cf22fa14f057a469David Lawrencemagic number as the first field. The purpose of the magic number is
4be63b1fd8c18dbeca1648d6cf22fa14f057a469David Lawrenceprincipally to validate that a pointer a subroutine has gotten really points
4be63b1fd8c18dbeca1648d6cf22fa14f057a469David Lawrenceto the type it claims to be. This helps detect problems caused by resources
70e5a7403f0e0a3bd292b8287c5fed5772c15270Automatic Updaterbeing freed prematurely, that have been corrupted, or that have not been
217f572018871cdf09db052a676b9933512cdbfaMark Andrewsproperly initalized. It can also be handy in debugging.
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews
ab023a65562e62b85a824509d829b6fad87e00b1Rob AusteinMagic numbers should always be the first field. They never require locking
217f572018871cdf09db052a676b9933512cdbfaMark Andrewsto access. As to the actual value to be used, something mnemonic is good:
2e8215dda9e102355baca77e4e59132eff8e2357Mark Andrews
2e8215dda9e102355baca77e4e59132eff8e2357Mark Andrews #define TASK_MAGIC 0x5441534BU /* TASK. */
2e8215dda9e102355baca77e4e59132eff8e2357Mark Andrews #define VALID_TASK(t) ((t) != NULL && \
2e8215dda9e102355baca77e4e59132eff8e2357Mark Andrews (t)->magic == TASK_MAGIC)
2e8215dda9e102355baca77e4e59132eff8e2357Mark Andrews
4be63b1fd8c18dbeca1648d6cf22fa14f057a469David Lawrence #define TASK_MANAGER_MAGIC 0x54534B4DU /* TSKM. */
4be63b1fd8c18dbeca1648d6cf22fa14f057a469David Lawrence #define VALID_MANAGER(m) ((m) != NULL && \
(m)->magic ==
TASK_MANAGER_MAGIC)
Unless the memory cost is critical, most objects should have a magic number.
The magic number should be the last field set in a creation routine, so that
an object will never be stamped with a magic number unless it is valid.
The magic number should be set to zero immediately before the object is
freed.
Magic values are generally private to the implementation of the type. I.e.
they are defined in the .c file, not the .h file.
Validation of magic numbers is done by routines that manipulate the type,
not by users of the type. Indeed, user validation is usually not possible
because the magic number is not public.
Magic number checking may become a build option in a future release. E.g.
struct foo {
ISC_MAGIC_DECLARATION
/* ... */
}
foo_create() {
/* ... */
ISC_MAGIC_SET(value);
}
foo_destroy() {
/* ... */
ISC_MAGIC_CLEAR(value);
}
#define FOO_MAGIC 0x00010203U
#define VALID_FOO(f) ISC_MAGIC_VALIDATE(f, FOO_MAGIC)
foo_dosomething(foo *f) {
REQUIRE(VALID_FOO(f));
}