I am reading the book named "Code Complete". In the book, there is an explanation of "dog-tag field".
Use dog-tag fields to check for corrupted memory. A "tag field" or "dog tag" is a field you add to a structure solely for the purpose of error checking.
Have you ever seen the actual usage of the "dog-tag" field in your software or in some software used by many users?
Considerable technological advances have come along since Vietnam, including the ability to use DNA to identify remains. But despite these advancements, dog tags are still issued to service members today.
The main purpose of the military dog tags is to identify soldiers that are wounded or killed while they are in action. These dog tags are allotted to the soldiers as a replacement of the plastic printed identity cards because of their resistance to harsh weather conditions and durability.
Today's identification tags identify vital information about the wearer: name, Social Security number, blood type and religious preference. During World War II there were only three religious categories that could be put on dog tags: P for Protestant, C for Catholic and H for Hebrew (Jewish).
In World War II, identification tags started to look more like today's standard-issue dog tags. They were metal and rectangular, with a notch in a lower corner. The soldier's information was imprinted on the metal tag. That notch was used to align the metal plate on the machine that embossed the information.
The "dog-tag" fields, or checksums, are still in use. They are primarily used in data transmission.
The memory in most computers, embedded and desktop, has improved in quality. There are fewer checks on memory and those checks are quick tests performed during power-up of a computer.
If your data is very critical and important data, you may want to use a 'dog-tag' or checksum field. This could prove useful when writing to hard drives.
Some error checking schemes store values that will help reconstruct the data if there is any corruption.
The field will need to be updated if any data member in the structure is intentionally changed. This will negatively impact the performance of your program.
What McConnell calls "dog-tags" is simply putting a field in a data structure that you initialize with a recognizable value. When the structure is freed, the tag field should be 'erased'.
struct foo {
unsigned int tag;
int bar;
char baz[20];
char* qux;
};
enum {
tag_freed = 0xcfcfcfcf,
tag_foo = 0x206f6f66, // "foo " in little-endian
};
struct foo* foo_alloc(void)
{
struct foo template = {tag_foo};
struct foo* p = malloc(sizeof struct foo);
if (p) {
*p = template;
}
return p;
}
int foo_validate(struct foo* p)
{
return p && (p->tag == tag_foo);
}
void foo_free(struct foo* p)
{
if (p) {
if (!foo_validate(p)) error_handler(/* ... */);
p->tag = tag_freed;
free(p);
}
}
There are several nice things about these kinds of tags:
The Windows kernel provides built in support for tagged memory allocations for drivers (in which case the tag is managed by the kernel pool manager and is external to the structure defined in the driver source code):
Modern C/C++ runtimes often give you the option to allocate extra space after an allocation, filled with a special sentinel value, and then check that value later to make sure it hasn't been overwritten.
Doing this manually is a lot of work for questionable benefit. I certainly wouldn't do it until I suspected that there was an actual memory overrun bug... and then only if, for some strange reason, I couldn't just do range checking in the accessor functions.
There are exceptions, relating to inter-processor communication utilities for certain unusual computer architectures, but in general I would not make such checking an explicit part of a class.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With