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[0]))

Sadly, its time has come to be deprecated. What did we replace them with?

     _countof(x)

Why?

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 y[3];

     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:

     #ifndef dim

     // Prefer to use _countof() directly, replacing dim()

     #pragma deprecated("dim")

     #define dim(x) _countof(x)

     #endif

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

     Dim, DIMOF

     CCHSIZEOF