Why add zero to the result of sizeof?

Consider the macro definition below, from Microsoft's Visual C runtime. What is the purpose of adding zero to the result of sizeof?

It may incur some implicit conversions, but this seems unimportant and unlikely.

1
2
3
4
template <typename _CountofType, size_t _SizeOfArray>
char (*__countof_helper(_UNALIGNED _CountofType (&_Array)[_SizeOfArray]))[_SizeOfArray];

#define __crt_countof(_Array) (sizeof(*__countof_helper(_Array)) + 0) 

In this context _UNALIGNED always expands to the language extension __unaligned:
https://docs.microsoft.com/en-us/cpp/cpp/unaligned?view=msvc-170

Thanks!
Personally, I think the "+ 0" part is to convert the return value from sizeof() which is size_t to int.

"Sorry about my bad English"
Somebody else wanted to know that:
https://stackoverflow.com/questions/59394312/why-does-the-msvc-count-of-implementation-add-0-to-the-result-of-sizeof

The answer they accepted was
The + 0 is added to prevent a potential occurrence of the Most Vexing Parse! Without it, an expression like sizeof(*__countof_helper(_Array)) could be taken as a function declaration in some circumstances.



Hmmm. The only times I do this are:
- to force a conversion (in this case from unsigned (size_t) to signed int)
- place-keeping, if I think I might want some other value in the future.
Neither apply here, though.
and the most common reason: "I don't know, but the code I copied off the internet did it"
does not really apply here since its part of VS, but things like this get copied without understanding to places that don't need the tweak.

I agree with parse problems. Because its in a macro, the author is being extra careful not to have it break on some edge case. This is another reason I avoid macros... if you are not overly careful with extra () pairs and various tricks, they can break.
Last edited on
It's MS and Windows. Whatever the original reason(s) for doing it, it is now established as The Way To Do Things.

Just as Charles Petzold formally made Systems Hungarian Notation the "from on high" way in his "Programing Windows" books, instead of Apps Hungarian.

MS showed some sense to finally realize that Hungarian Notation was counter-intuitive and potentially harmful.
Personally, I think the "+ 0" part is to convert the return value from sizeof() which is size_t to int.
Good idea, but the type of sizeof(e) + 0 is size_t unless size_t is smaller than int. See [expr.arith.conv] for the actual rules:
https://eel.is/c++draft/expr.arith.conv

Therefore I consider this an unlikely explanation, not least because it would be surprising if it did occur; why should the type of __crt_countof(my_array) change signedness between platforms, inviting undefined behavior?

The [Stack Overflow] answer they accepted

Seems unlikely.

First, declarations are not expressions or type names, so any attempt to sizeof(declaration), such as
sizeof(int x)
doesn't compile. So it seems unlikely that *__countof_helper(_Array) could be interpreted as a declaration, even if we ignore that it is never a declaration according to standard C++.

Second, if sizeof(*__countof_helper(_Array)) is itself a function declaration, than there's no return type, the name of the function is sizeof, and/or somehow *__countof_helper(_Array) is a type name.

I believe the most vexing parse idea can be discounted.

It's MS and Windows. Whatever the original reason(s) for doing it, it is now established as The Way To Do Things.

The only other options I can recall are that it could interact with an external tool or maybe has something to do with an edge case thanks to some language extension.

Or, it could be a typo. :-)
Last edited on
Last edited on
The number of typos that have become established TWTDT are legion. :Þ

Nice bit of discussion, totally irrelevant, so quite refreshing the "obligatory" Flame Wars aren't invoked. :D
There has been quite a lot of flaming recently. Kinda sucks, because I just want to talk about programming.

Cheers!
Cheers, guys! 4 Programming.
Registered users can post here. Sign in or register to post.