Live data from Hacker News

How to find size of an array in C without sizeof

arjunsreedharan.org

21–30 of 212 posts

Re: How to find size of an array in C without sizeof

#21
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.

Re: How to find size of an array in C without sizeof

#22

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))[…

I 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.

Re: How to find size of an array in C without sizeof

#23
post #3

Despite the argument at the end, this is undefined behavior in the latest C specification. The code dereferences a pointer one past the last element. C11 6.5.6/8: If the result points one past the last element of the array object, it shall not be used as the operand of a unary * operator that is evaluated

I think the authors of the spec really meant something else: reading/writing a memory location past the end of the array is illegal. But here "*" is used only in an address computation, not to actually access memory.

Shows how difficult it is to get a spec right.

So, IMO, you are right, the code in the article is illegal (strictly speaking).

But I think it is likely that most compilers would still allow it, because that clause in the spec essentially exempts the compiler from adding an explicit bounds check.

Re: How to find size of an array in C without sizeof

#24

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))[…

I 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.

Indeed, 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.

Re: How to find size of an array in C without sizeof

#25
post #12

this is undefined behavior. &arr + 1 can overflow. There's no guarantee &arr isn't near memory end boundary. &arr + 1 is converted at compile time to rbp - X where X is an integer determined by the compiler similarly to how sizeof works. Basically ptr + integer requires the compiler to determine the sizeof ptr's type.

this is undefined behavior. &arr + 1 can overflow

No. From 6.5.6 Additive operators:

7 For the purposes of these operators, a pointer to an object that is not an element of an array behaves the same as a pointer to the first element of an array of length one with the type of the object as its element type.

8 [...] if the expression P points to the last element of an array object, the expression (P)+1 points one past the last element of the array object [...] If both the pointer operand and the result point to elements of the same array object, or one past the last element of the array object, the evaluation shall not produce an overflow; otherwise, the behavior is undefined. If the result points one past the last element of the array object, it shall not be used as the operand of a unary * operator that is evaluated.

So &arr + 2 can overflow, and &arr + 1 cannot be dereferenced, but &arr + 1 shall not overflow and is not undefined behaviour.

Re: How to find size of an array in C without sizeof

#26

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))[…

> 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?

Re: How to find size of an array in C without sizeof

#27

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))[…

A more detailed article here: 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-...

MSVC has a built in _countof: http://stackoverflow.com/questions/4415530/equivalents-to-ms...

Re: How to find size of an array in C without sizeof

#28

I'm surprised at all of the comments calling this stupid or pointless. The point is not that you should this trick in lieu of sizeof; the point is to shed light on a subtly of C arrays.

You've been on here 4 years and are surprised at the top comments criticizing the content of a post? :)

There's a reason this meme exists: http://i.imgur.com/Z6pFTjj.jpg

Re: How to find size of an array in C without sizeof

#29

The result you get with this trick is signed, while the result you get with sizeof is unsigned. Edit: Just to clarify, what you get is ptrdiff_t instead of size_t. So if array size is greater than PTRDIFF_MAX, you get undefined behavior [1]. [1] http://en.cppreference.com/w/c/types/ptrdiff_t

How likely do you run into array bigger than 2gb?

Re: How to find size of an array in C without sizeof

#30

I'm surprised at all of the comments calling this stupid or pointless. The point is not that you should this trick in lieu of sizeof; the point is to shed light on a subtly of C arrays.

Quite. This exactly the sort of thing that makes C such a fun language.

I'm not sure if it's a praise for C though. Arcane design and lack of clarity might be fun to decipher, but it's not something that you'd want to see in the programming language.
Post reply on HN