Open dhh1128 opened 10 years ago
Consider the following scenario:
uint64_t n;
#define WRITE_TREE(tree) \
if (ok) { \
n = tree.insert_offset; \
ok = ok && WriteToReport(file, (uint8_t*)&n, sizeof(n)); \
ok = ok && WriteToReport(file, (uint8_t*)&n, sizeof(n)); \
n = tree.item_count; \
ok = ok && WriteToReport(file, (uint8_t*)&n, sizeof(n)); \
ok = ok && WriteToReport(file, (uint8_t*)ds->tree.buffer, n); \
}
WRITE_TREE(planetTree);
WRITE_TREE(starTree);
WRITE_TREE(asteroidTree);
WRITE_TREE(cometTree);
This code doesn't compile because the data type of cityBag and stateBag is different from the data type of the others--and cityBag lacks an _itemCount member, so the line that assigns ds->bag._itemCount to n won't compile.
We could write template functions and specialize them for the two different bag datatypes, but this would require two new function declarations and two function impls, and lots of parameter mgmt, all to "reduce" code size.
A cleaner solution might be to say, "WRITE_BAG(cityBag) is like WRITE_BAG(streetBag) except omit two lines". The question is whether we could do that in a way that is A) terse enough to save significant effort; B) easy to debug; C) obvious.
Here's another example of code that uses macros to be less verbose. We want something like this.
#define SAVE_TREE(tree) if (bSuccess) bSuccess = SaveTree(ds->tree, pFile)
SAVE_TREE(planetTree);
SAVE_TREE(starTree);
SAVE_TREE(asteroidTree);
SAVE_TREE(cometTree);
#undef SAVE_TREE
One way that generics are inadequate is that they can't be templatized by a variable, only by a constant. Another is that generics are verbose -- they don't offer a way to decrease repetitive text unless there's significant code being abstracted away. Another is that they sometimes require a different invocation for each different type (DoSomething, DoSomething).
Use cases:
Requirements:
a. Must still be debuggable/obvious. (This may suggest that expanded form is present but just hidden by default in the code.) b. Can't break syntax. c. Must support variadic args with compile-time reflection of them so I can get variadic arg 1, 2, ... N