0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark AndrewsCopyright (C) 1999-2002, 2004, 2016 Internet Systems Consortium, Inc. ("ISC")
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark AndrewsThis Source Code Form is subject to the terms of the Mozilla Public
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark AndrewsLicense, v. 2.0. If a copy of the MPL was not distributed with this
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrewsfile, You can obtain one at http://mozilla.org/MPL/2.0/.
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews$Id: magic_numbers,v 1.7 2004/03/05 05:04:50 marka Exp $
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob HalleyMagic Numbers
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
750a62493d3a79e7873026661cd18ec94f8ab0d9Mark Andrewsproperly initialized. It can also be handy in debugging.
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 #define TASK_MAGIC 0x5441534BU /* TASK. */
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley #define VALID_TASK(t) ((t) != NULL && \
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley (t)->magic == TASK_MAGIC)
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 HalleyUnless the memory cost is critical, most objects should have a magic number.
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 HalleyThe magic number should be set to zero immediately before the object is
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 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 HalleyMagic number checking may become a build option in a future release. E.g.
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley struct foo {
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley ISC_MAGIC_DECLARATION
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley foo_create() {
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley ISC_MAGIC_SET(value);
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley foo_destroy() {
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley ISC_MAGIC_CLEAR(value);
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley #define FOO_MAGIC 0x00010203U
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley #define VALID_FOO(f) ISC_MAGIC_VALIDATE(f, FOO_MAGIC)
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley foo_dosomething(foo *f) {
767d29c43d98bae8ea95f0ccd2b9653cbcd43310Bob Halley REQUIRE(VALID_FOO(f));