Live data from Hacker News

How to find size of an array in C without sizeof

arjunsreedharan.org

31–40 of 212 posts

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

#31
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…

But arr != &arr even though they have the same value. #8 applies to arr (P), but in the post OP is using &arr which is a ptr to array[x] and doesn't apply to it.

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

#33

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

IIRC it is canonically called NELEMS(a).

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

#34
post #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 t…

I don't think this is illegal. What is the clause in the spec that allows &arr[1]? I would try and see if it also applies to (&arr)[1].

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

#35
post #30

Earlier quoted context omitted.

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.

Doesn't every language turns into insanity to decipher once you look close enough?

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

#36

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?

Probably not very likely, but keep in mind that this method could also be used without actually allocating the array -- akin to the 'offsetof()' macro. (Which is undefined behavior.)

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

#38
post #31

Earlier quoted context omitted.

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…

But arr != &arr even though they have the same value. #8 applies to arr (P), but in the post OP is using &arr which is a ptr to array[x] and doesn't apply to it.

Can't we declare pointer of type &arr, assign it there and be sure that it points to equivalent of array[1] of &arr? If yes, then is it logically possible to have UB on that?

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

#40

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?

Today, with ML, big data and similar applications, that might be often.
Post reply on HN