Re: Converting Visual C++ 6.0 application to Unicode

Tech-Archive recommends: Repair Windows Errors & Optimize Windows Performance



Thanks. That clarifies it. I've clearly been ignoring the fine points of templates.
joe

On Wed, 07 Mar 2007 11:29:08 -0600, "Doug Harrison [MVP]" <dsh@xxxxxxxx> wrote:

On Wed, 07 Mar 2007 10:37:43 -0500, Joseph M. Newcomer
<newcomer@xxxxxxxxxxxx> wrote:

On Wed, 07 Mar 2007 11:07:15 +0000, David Lowndes <DavidL@xxxxxxxxxxxxxxx> wrote:

_countof is not a template; it is a macro defined in stdlib.h, and it is defined as

#define _countof(x) ((sizeof(x)) / sizeof(x[0]))

It is a template for C++ in the newer VS2005 version:

/* _countof helper */
#if !defined(_countof)
#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
#endif

The template version is much more effective as it can't be so easily
abused as the simple #define version could.

Interesting. But it is so complex that I haven't figured out what it is trying to do, or
what problem it has solved. I've spent some time staring at this code, and I'm not seein
where the _SizeOfArray is coming from or how the use of &_Array, which isn't even a bound
parameter of the template is used. Seriously, can you explain this? There's some mystery
of templates I'm not seeing here...
joe

The identifier __countof_helper is the name of a function template whose
parameter is a reference to an array of the type
_CountofType[_SizeOfArray]; this parameter is named _Array. The function
returns a pointer to an array of char that has size _SizeOfArray, so this
array has the same number of elements as _Array. The macro _countof calls
__countof_helper on an argument _Array and dereferences the function
result, which is a pointer to the char array just mentioned. Then sizeof
yields the size of the char array, which as already mentioned, has the same
number of elements as _Array, and since sizeof(char) == 1 by definition, it
gives the "count of" _Array.

So that's what it is and what it does. This is why it does it.

1. Array reference arguments don't undergo the array to pointer conversion,
which is the key to the technique. Here's the __countof_helper parameter:

_CountofType (&_Array)[_SizeOfArray]

The template parameters _CountofType and _SizeofArray are deduced from the
array passed to the function. Because _Array is a reference, the argument
that is bound to it can only be an array (this is what makes it better than
the C _countof), and because it isn't converted to a pointer, the number of
elements is available as _SizeOfArray.

2. It would be nice for _countof to remain a purely compile-time
expression, like sizeof and the inferior C version of _countof. It is for
this reason that _countof_helper returns a pointer to a char array with the
same number of elements as _Array. Because expressions inside sizeof aren't
evaluated, i.e. they generate no code, _countof can dereference this
returned pointer inside sizeof to get the number of elements in _Array.
(This is better than more straightforward approaches that make _countof a
function template that returns _SizeOfArray.)

To sum up, the C++ _countof calls a function __countof_helper, but no code
is executed because it's done inside sizeof. The whole point is to do
compile-time processing on types, so that given an array, you can determine
its length. The C++ version is superior to the C version because the former
only works on arrays, while the latter works on pointers as well, which is
wrong.
Joseph M. Newcomer [MVP]
email: newcomer@xxxxxxxxxxxx
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
.



Relevant Pages

  • Re: Listing objects
    ... When Template is instantiated, it instantiates Control, which, in turn, instantiates Data. ... Another way would be to have a global array and save all objects there by reference. ...
    (comp.lang.php)
  • Re: Question About temlates.
    ... >will act like a dynamic array. ... You're describing the right approach to creating a template from a ... a dynamic array generally means that there's at least one ... many elements in the constructor. ...
    (alt.comp.lang.learn.c-cpp)
  • Re: nested conditional that can identify parent page?
    ... and specify the files in the array including ... try to make as little php and html mix as possible, have a template ...
    (alt.php)
  • Re: Converting Visual C++ 6.0 application to Unicode
    ... The template version is much more effective as it can't be so easily ... where the _SizeOfArray is coming from or how the use of &_Array, ... The macro _countof calls ... like sizeof and the inferior C version of _countof. ...
    (microsoft.public.vc.mfc)
  • Re: How can I extract variables from a ruby snippet
    ... multi-dimensional array, ... Otherwise, you could execute the template using erb, and use ... methods have been called on that dummy object. ... you pass in a hash of 'local_assigns', ...
    (comp.lang.ruby)