title: Reliably determine the number of elements in an array
body: <p>Every C programmer can determine the number of elements in an array with this well-known macro:</p>
  
  <pre><code>#define NUM_ELEMS(a) (sizeof(a)/sizeof 0[a])
  </code></pre>
  
  <p>Here is a typical use case:</p>
  
  <pre><code>int numbers[] = {2, 3, 5, 7, 11, 13, 17, 19};
  printf("%lu\n", NUM_ELEMS(numbers));          // 8, as expected
  </code></pre>
  
  <p>However, nothing prevents the programmer from accidentally passing a pointer instead of an array:</p>
  
  <pre><code>int * pointer = numbers;
  printf("%lu\n", NUM_ELEMS(pointer));
  </code></pre>
  
  <p>On my system, this prints 2, because apparently, a pointer is twice as large as an integer. I thought about how to prevent the programmer from passing a pointer by mistake, and I found a solution:</p>
  
  <pre><code>#define NUM_ELEMS(a) (assert((void*)&amp;(a) == (void*)(a)), (sizeof(a)/sizeof 0[a]))
  </code></pre>
  
  <p>This works because a pointer to an array has the same value as a pointer to its first element. If you pass a pointer instead, the pointer will be compared with a pointer to itself, which is almost always false. (The only exception is a recursive void pointer, that is, a void pointer that points to itself. I can live with that.)</p>
  
  <p>Accidentally passing a pointer instead of an array now triggers an error at runtime:</p>
  
  <pre><code>Assertion `(void*)&amp;(pointer) == (void*)(pointer)' failed.
  </code></pre>
  
  <p>Nice! Now I have a couple of questions:</p>
  
  <ol>
  <li><p>Is my usage of <code>assert</code> as the left operand of the comma expression valid standard C? That is, does the standard allow me to use <code>assert</code> as an expression? Sorry if this is a dumb question :)</p></li>
  <li><p>Can the check somehow be done at compile-time?</p></li>
  <li><p>My C compiler thinks that <code>int b[NUM_ELEMS(a)];</code> is a VLA. Any way to convince him otherwise?</p></li>
  <li><p>Am I the first to think of this? If so, how many virgins can I expect to be waiting for me in heaven? :)</p></li>
  </ol>