From: Giovanni Dicanio on
"RB" <NoMail(a)NoSpam> ha scritto nel messaggio
news:eHRumPz5KHA.3292(a)TK2MSFTNGP06.phx.gbl...

> Thanks Giovanni

You are welcome.


> , I can see that a pointer would a misconceived size, and I will
> copy this link. But I have never really done the template thing so will
> have to
> read on that first.

The "template thing" is smart (kudos to those C++ gurus who implemented
that):

template <typename _CountofType, size_t _SizeOfArray>
char (*__countof_helper(UNALIGNED _CountofType
(&_Array)[_SizeOfArray]))[_SizeOfArray];

Basically, the above is the declaration of a template function (whose name
is __countof_helper), that accepts as input an array of any type
(_CountofType template parameter) and of any size (_SizeOfArray template
parameter). This function returns an array of char's of the *same size* as
the input array.

Then, the _countof macro is defined as just taking the size of this char
array (considering that 1 char == 1 byte):

#define _countof(_Array) sizeof(*__countof_helper(_Array))

Note that the template function does not need to be defined; the
*declaration* is just fine.

It is important to note that if something different from a static array
(e.g. a pointer) is passed to __countof_helper (via _countof macro), then it
is impossible for the C++ compiler to match __countof_helper template
arguments, and as a result of that there is an error at compile time.

Given that (wrong) code:

BYTE * p = new BYTE[100];
size_t s = _countof(p);

VC10 (in VS2010) correctly gives the following compile-time error:

error C2784: 'char (*__countof_helper(_CountofType
(&)[_SizeOfArray]))[_SizeOfArray]' : could not deduce template argument for
'_CountofType (&)[_SizeOfArray]' from 'BYTE *'


Giovanni


From: RB on
Thank you !
Excellent expound on understanding templates. I saved
it in the same reference file as the below that I also saved
to complete the future proof implementation technic.

// From VS2010's <atldef.h> header file, it can be read:
<code>
#if !defined(__cplusplus)
#define _countof(_Array) (sizeof(_Array) / sizeof(_Array[0]))
#else
extern "C++"
{
template <typename _CountofType, size_t _SizeOfArray>
char (*__countof_helper(UNALIGNED _CountofType
(&_Array)[_SizeOfArray]))[_SizeOfArray];
#define _countof(_Array) sizeof(*__countof_helper(_Array))
}
#endif
</code>