TE
科技回声
首页24小时热榜最新最佳问答展示工作
GitHubTwitter
首页

科技回声

基于 Next.js 构建的科技新闻平台,提供全球科技新闻和讨论内容。

GitHubTwitter

首页

首页最新最佳问答展示工作

资源链接

HackerNews API原版 HackerNewsNext.js

© 2025 科技回声. 版权所有。

How to find size of an array in C without sizeof

420 点作者 ashishb4u超过 8 年前

22 条评论

ycmbntrthrwaway超过 8 年前
The result you get with this trick is signed, while the result you get with sizeof is unsigned.<p>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].<p>[1] <a href="http:&#x2F;&#x2F;en.cppreference.com&#x2F;w&#x2F;c&#x2F;types&#x2F;ptrdiff_t" rel="nofollow">http:&#x2F;&#x2F;en.cppreference.com&#x2F;w&#x2F;c&#x2F;types&#x2F;ptrdiff_t</a>
评论 #13259976 未加载
评论 #13260637 未加载
评论 #13259822 未加载
millstone超过 8 年前
I&#x27;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.
评论 #13259708 未加载
评论 #13259727 未加载
评论 #13260668 未加载
评论 #13259807 未加载
arjun024超过 8 年前
Author of the article here. There&#x27;s no intention here to encourage people to use this in code (in fact the opposite). This article is more of a &quot;Did you know cool shit like this exist?&quot;.
评论 #13262528 未加载
评论 #13261494 未加载
Stratoscope超过 8 年前
Whether you use this method of getting the number of elements in an array or the more traditional sizeof method, <i>please</i> encapsulate the logic in a macro.<p>Instead of writing either of these:<p><pre><code> size_t length = sizeof array &#x2F; sizeof array[0]; size_t length = (&amp;array)[1] - array; </code></pre> Define this macro instead:<p><pre><code> #define countof( array ) ( sizeof(array) &#x2F; sizeof((array)[0]) ) </code></pre> Or if you must:<p><pre><code> #define countof( array ) ( (&amp;(array))[1] - (array) ) </code></pre> And then you can just say:<p><pre><code> size_t length = countof(array); </code></pre> Edit: I used to call this macro &#x27;elementsof&#x27;, but it seems that &#x27;countof&#x27; is a more common name for it and is a bit more clear too - so I&#x27;m going to run with that name in the future.
评论 #13260377 未加载
评论 #13259804 未加载
评论 #13259800 未加载
评论 #13259767 未加载
评论 #13259834 未加载
评论 #13261047 未加载
icedchai超过 8 年前
Interesting. I&#x27;ve been working with C for almost 30 years (first taught it to myself when I was 14) and never thought about the actual <i>type</i> of <i>array</i>.
评论 #13261265 未加载
评论 #13260339 未加载
minipci1321超过 8 年前
For the completeness sake, the size of an array can also be computed via linker symbols, see for example: <a href="http:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;29901788&#x2F;finding-the-last-variable-in-attribute-section" rel="nofollow">http:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;29901788&#x2F;finding-the-last...</a>.<p>Same constraints apply (pointer arith).<p>I am not sure why this method, applied to ordinary arrays, would be preferred to sizeof (), but since we&#x27;re shedding light here...<p>EDIT: pointer arith constraints only apply if we compute the difference (end - beg) in the C code. We could also do that in the linker script itself, and I don&#x27;t recall whether or not C semantics of ptrdiff_t would be preserved in that case. Such preservation doesn&#x27;t seem very probable to me, so potentially this method might allow to avoid overflows (or to move them much higher) -- to be checked in the &#x27;ld&#x27; doc!
评论 #13260435 未加载
pmiller2超过 8 年前
Was anyone else&#x27;s first thought &quot;Hmm... cool,&quot; followed by &quot;I hope nobody asks me this on an interview?&quot;
评论 #13260051 未加载
评论 #13260186 未加载
hnfairy超过 8 年前
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.<p>C11 6.5.6&#x2F;8:<p>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
评论 #13259682 未加载
评论 #13259621 未加载
评论 #13259774 未加载
angry_octet超过 8 年前
While this is as interesting as any c arcana, I truly hope that people are not passing around pointers to arrays and then using sizeof(array)&#x2F;sizeof(elem) to figure out how big they are, like they are stuck in a first year programming assignment that denies them the use of malloc, so they use C99 VLAs everywhere.
gruez超过 8 年前
How is this better than the sizeof method? This looks like a clever way to access sizeof information without explicitly using the sizeof operator.
评论 #13261332 未加载
评论 #13260338 未加载
评论 #13259827 未加载
Nimitz14超过 8 年前
Why do we dereference the array pointer? Wouldn&#x27;t that give us the value at the address when we just want the address? Also wouldn&#x27;t the subtraction just give us a number of bytes and thus we&#x27;d still need to divide by sizeof(int))?
评论 #13263800 未加载
jheriko超过 8 年前
there is a classic mistake here... the idea that pointer arithmetic does not rely on sizeof.<p>that&#x27;s the entire mystery opened and closed afaik. sure you can use some obscure notation if you like, but why not just use sizeof?
russkrayer超过 8 年前
Thanks for posting this question. The responses are very interesting.
halayli超过 8 年前
this is undefined behavior. &amp;arr + 1 can overflow. There&#x27;s no guarantee &amp;arr isn&#x27;t near memory end boundary. &amp;arr + 1 is converted at compile time to rbp - X where X is an integer determined by the compiler similarly to how sizeof works.<p>Basically ptr + integer requires the compiler to determine the sizeof ptr&#x27;s type.
评论 #13259789 未加载
评论 #13260360 未加载
Etheryte超过 8 年前
Given how many bugs &amp; errors stem from simple fails in range checks etc, I would much rather go with the tried and true way rather than use something &quot;clever&quot;.<p>Quoting <a href="http:&#x2F;&#x2F;stackoverflow.com&#x2F;a&#x2F;16019052&#x2F;1470607" rel="nofollow">http:&#x2F;&#x2F;stackoverflow.com&#x2F;a&#x2F;16019052&#x2F;1470607</a><p><pre><code> Note that this trick will only work in places where `sizeof` would have worked anyway.</code></pre>
评论 #13259617 未加载
utopcell超过 8 年前
nice exposition to c array types.<p>in c++, a compile-time equivalent to sizeof would be:<p><pre><code> template&lt;typename T, size_t N&gt; size_t sz(T(&amp;)[N]) { return N; }</code></pre>
angeladur超过 8 年前
I would do this only when I am obfuscating code.
disposablezero超过 8 年前
Many implementations historically also allocated enough memory to include one extra element at the end of the array.
评论 #13259995 未加载
slobdell超过 8 年前
That pun in the first sentence alone made the article worth it.
stirner超过 8 年前
The printf commands say &quot;the address of...&quot; but proceed to print out the value, not address.
评论 #13260129 未加载
Chinjut超过 8 年前
C is such a boondoggle of a language... We&#x27;re condemned to forever explore its every weird nook and cranny for historical reasons, rather than because it is the cleanest, best approach to things possible.
评论 #13259969 未加载
Maro超过 8 年前
I haven&#x27;t written C in a while, but I think this is pretty stupid. sizeof() is a compile-time thing in C, so it&#x27;s substituted with a number by the time you get an executable. See:<p><a href="http:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;671790&#x2F;how-does-sizeofarray-work" rel="nofollow">http:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;671790&#x2F;how-does-sizeofarr...</a><p>I think this is effectively doing the same thing, but in a non-standard way; ie. I think `int n = (&amp;arr)[1] - arr;` is substituted with the actual the number by the compiler the same way sizeof() would be, only noone will know wtf is going on.<p>Disclaimer: I didn&#x27;t look at the generated code to confirm; I guess it could even be compiler&#x2F;runtime dependent.
评论 #13259634 未加载