4 ms·
Whether you use this method of getting the number of elements in an array or the more traditional sizeof method, please encapsulate the logic in a macro. Inste
by Stratoscope 10y ago
Whether you use this method of getting the number of elements in an array or the more traditional sizeof method, please encapsulate the logic in a macro.
Instead of writing either of these:
size_t length = sizeof array / sizeof array[0];
size_t length = (&array)[1] - array;
Define this macro instead:
#define countof( array ) ( sizeof(array) / sizeof((array)[0]) )
Or if you must:
#define countof( array ) ( (&(array))[1] - (array) )
And then you can just say:
size_t length = countof(array);
Edit: I used to call this macro 'elementsof', but it seems that 'countof' is a more common name for it and is a bit more clear too - so I'm going to run with that name in the future.
- gpderetta 10y agoI doubt the author meant for this trick to be actually used, they were just showing how pointers to arrays are typed correctly in a clever way.
- Stratoscope 10y agoIndeed, one could hope that is the case! :-) But my point with suggesting the macro applies equally to the more traditional sizeof division. I have seen code that divides the two sizeofs every time an array length is needed. I think it's better to put that calculation in a macro so you only do it in one place.
- markrages 10y agoYou are dividing one constant by another -- surely that would be handled at compile time?
- Stratoscope 10y agoYou are correct, the compiled code will be the same whether you use a macro or not. In fact, this is true for any C macro. A macro is merely a source code text substitution done by the preprocessor. Using a macro is exactly the same as writing out the equivalent macro expansion everywhere you use it. My suggestion to use a macro is not because of any difference in the compiled code, but to improve the readability of the source code.
- saifelse 10y agoWhile it may be optimized, I think the suggestion is that instead of using a hack repeatedly, it is arguably better to be DRY and abstract it away.
- babuskov 10y ago> please encapsulate the logic in a macro. Why? When reading such code, it means I would have to go and lookup a macro definition. So, there's a clear drawback. What's the benefit that makes it worthwhile?
- Tempest1981 10y agoFaster to read, and keeps the reader's mind at a semantically higher level.
- babuskov 10y agoProvided that he knows about the macro. Otherwise it's slower and if you switch projects often it requires that you remember what's it about. I guess it could be useful for teams working together on bigger codebases.
- Namrog84 10y ago1. An appropriate named macro shouldn't cause you to need to investigate it unnecessarily 2 most IDEs allow simple hover over and see macro definition without having to break much flow.
- verdax_1 10y agoI might go a step further and append "an appropriately implemented macro". Just because something has a good name doesn't mean it's not filled with crazy. Otherwise I totally agree with your point.
- EpicEng 10y agoI disagree. If you've progressed beyond the absolute beginner phase you know exactly what that line is when you see it. You've only put in work to obfuscate your code a bit and (potentially) cause conflicts with other units whose author had the same idea.
- jjnoakes 10y ago
- Tempest1981 10y agoA more detailed article here: http://www.g-truc.net/post-0708.html http://www.g-truc.net/post-0708.html with a cleaner way to do _countof using a template in C++ 11. You can also use the template technique to pass a fixed size array to a function, and have the function determine the array size (without needing a 2nd length param, or null terminator element). Similar to strcpy_s(): http://stackoverflow.com/questions/23307268/how-does-strcpy-s-work http://stackoverflow.com/questions/23307268/how-does-strcpy-... MSVC has a built in _countof: http://stackoverflow.com/questions/4415530/equivalents-to-msvcs-countof-in-other-compilers/13747781 http://stackoverflow.com/questions/4415530/equivalents-to-ms...
- Stratoscope 10y agoThanks for the interesting references! While we're talking macros, anyone who reads the g-truc.net article should feel itchy after seeing the countof macro in their example: #define countof(arr) sizeof(arr) / sizeof(arr[0]) Two problems here: 1. The last use of 'arr' doesn't have 'arr' wrapped in parenthesis. 2. The entire expression is not wrapped in parentheses either. If you write a macro that does any calculation like this, play it safe and put parens around every macro argument and parens around the entire expression too. Otherwise you never know what operator precedence will do to you.
- Tempest1981 10y agoGreat point, about proper macro defines. And use do/while wrappers (without a trailing semicolon) where needed: https://kernelnewbies.org/FAQ/DoWhile0 https://kernelnewbies.org/FAQ/DoWhile0
- wruza 10y agoIIRC it is canonically called NELEMS(a).
- int_19h 10y agoI don't know if there's such a thing as "canonical" here. In MSVC, it's _countof (and it's in one of the standard headers).
- mianos 10y agoPlease don't replace a one line, obviously recognised by every C programmer since the beginning of time, sizeof(array) / sizeof (type) with some macro that not everyone knows. But alas, I've only been a C programmer for 30 years so I probably don't know what is cool these days.
- brian-armstrong 10y agoWhy a macro and not a static inline function?
- Stratoscope 10y agoThat's a good question! Can you share the code for that function?
- deleted 10y ago[deleted]
- EpicEng 10y agoHow exactly do you intend to get an array from a function argument?