Derived Information

I propose that DerivedInformation be deleted and be replaced with DerivedData. --JonGrover

From SelfDocumentingCode.

When information is redundantly maintained, don't. Instead, derive the redundant copy from other sources.

[Huh? "When information is redundantly maintained, don't [be redundantly maintained]"? Perhaps you mean "When you maintain information redundantly, don't"? ]

See also OnceAndOnlyOnce.

Many times when writing code you discover that you need two very similar sets of information. Typically, one set can be derived from the other. Instead of maintaining both sets independently by hand, which is errorprone, maintain only one and derive the rest of the information automatically.

For instance, it is an unfortunate common practice to write

 #define SIZE 100

char array[SIZE]; int i;

for( i = 0; i < SIZE; i++ ) { /* do something with array[i] */ ; }

However, it is far superior to write

 #define SIZE 100

char array[SIZE]; int i;

for( i = 0; i < sizeof array / sizeof *array; i++ ) { /* do something with array[i] */ ; }

as the size of the array comes for free from the compiler (with some sizeof magic). Note, while the sizeof(char) is strictly 1 by ANSI, you may which to change the type of the array in the future. Say, to wchar_t.

Indeed, a handy macro I use for this particular incarnation of DerivedInformation is:

 /* Returns the size of an array defined in local lexical scope */
 #define NUM_ELEM(x) (sizeof (x) / sizeof *(x))

The moniker violates MeaningfulNames' corollary about abbreviations, but it is such a common operation, it needed to be short.

Similar sizeof magic is something along the lines of

 pFoo = malloc( sizeof *pFoo );

That way you can be immune to changes to pFoo's type.

Other interesting ways of using DerivedInformation would be defining XML tag names to be identical to class names that you can instantiate through reflection to actually read in the object. That way you don't have to maintain a separate table of class <-> tag associations.

Basically, like many SelfDocumentingCode techniques, this boils down to simplification. If you don't have to document, "change that when you change this," your document/comments are that much thinner.

Fascinatingly, many people fail to extend this notion towards actual documentation, relying instead on manpower generated diagrams updated through traceability.
However, your suggestions make the code more difficult to read. The first for loop example is far more intuitive, and thus superior. Also, even though I programmed C for several years, it's not obvious to me whether your examples will work in all circumstances with all compilers.

Technically some compilers don't parse sizeof operand correctly, instead requiring sizeof(operand). The NUM_ELEM macro does work properly in all environments I have ever used, but if you're paranoid, you could further guard it by surrounding the *(x) with a further set of parentheses.

 /* Returns the size of an array defined in local lexical scope */
 #define NUM_ELEM(x) (sizeof (x) / sizeof (*(x)))

Does this complication affect you? Not really. Does this matter to the point above? Definitely not. Broken compilers only break the examples, not the Pattern.

Perhaps if the macro name was SIZE_OF_ARRAY it would be easier to read. I would certainly question the readability of

 pFoo = malloc( 48 );

or even

 pFoo = malloc( sizeof Foo )

especially if pFoo had been changed in maintenance to be a FooSubclass whose size > sizeof Foo. In other words, it's lying and therefore unreadable, not to mention broken.

"More on Getting the Number of Array Elements" and More on Getting the Number of Array Elements starts with the
 #define NUM_ELEM(x) (sizeof (x) / sizeof (*(x)))
technique, then improves it with some C++ magic. Is the result so much better that we should post it here and use it from now on (in C++ code)?

What is the difference between DerivedData and DerivedInformation? If there isn't a difference, then shouldn't this page be titled Deriveddata?

CategoryData? CategoryInformation

CategoryCee CategoryCeeSharp CategoryCpp


EditText of this page (last edited April 10, 2013) or FindPage with title or text search