Posted by Riki June
I’ve been doing some tidy up work in the driver code, and would like to draw your attention to a little something you will know too well:
#define dim(x) (sizeof(x)/sizeof(x))
Sadly, its time has come to be deprecated. What did we replace them with?
a) It’s bad form to use Clipboard Inheritance (aka copy-n-paste)
b) _countof(x) is new and improved!
In CE6 we added _countof() to the standard headers. It is a drop in replacement to get the count of an array with a nice little side effect. Notice the following:
int* x = y;
const int count = dim(x);
Huge bug! The code tries to get the count of a pointer, the compiler happily compiles it, and now there is a nasty run-time bug to find.
But if _countof() is used and done so in c++, there will be compiler error:
error C2784: 'char (*__countof_helper(_CountofType (&)[_SizeOfArray]))[_SizeOfArray]' : could not deduce template argument for '_CountofType (&)[_SizeOfArray]' from 'int *'
It’s a bit of a nasty error – due to _countof() using some template tricks to verify ‘x’ is really an array, not a pointer. But, as the saying goes, “Never put off to run-time, what can be done at compile time”. Those c++ gurus in the audience might be interested in the definition of _countof(), which is in public\common\sdk\inc\stdlib.h (as well as some ATL/MFC headers).
So what happens in a C file when that macro is used?
The same behavior as previously: it complies and you have a nasty bug to find. So this macro has the same behavior as previously in all cases except attempting to get the count of a pointer in a c++ file, in which it gives a “nice” loud compiler error.
So I implore you to start using _countof() in CE6 projects.
For those who wish to go further, ‘dim’ and ‘ARRAY_SIZE’ can be depreciated by adding some code to a common BSP header:
// Prefer to use _countof() directly, replacing dim()
#define dim(x) _countof(x)
The complier will generate this warning if ‘dim’ is used:
warning C4995: 'dim': name was marked as #pragma deprecated
But for now an ode to those fallen macros in my clean ups, so long to:
ARRAYSIZE, ARRAY_SIZE, ARRAYSIZEOF, ARRSIZE, SIZEOF_ARRAY, ARRAY_LENGTH
NUM_ELEMENTS, NELEMS, NUM, NUMBER_OF_ARRAY
TABLE_COUNT, COUNTOF, ItemCount