Hacker News new | past | comments | ask | show | jobs | submit login

This is the first time I have seen sizeof used like this:

  sizeof( &array[0] )
This looks equal to:

  sizeof( array )
at first glance, which would give the size of the entire array in bytes, but of course the &array[0] expression is really:

  &*( array + 0 )
which simplifies to:

  array + 0 
which is a pointer. And using sizeof on it gives the size of a pointer to int.

Edit: (&* array) will also give a pointer.

---

This is just a really convoluted way to write 2:

   &array[2] - &array[0]

   &*(array+2) - &*(array+0)

   (array+2) - (array+0)

   2 - 0
Again I have never seen this written in such fashion.



Here are the relevant parts of the C standard:

C89 3.3.3.4

"The sizeof operator... When applied to an operand that has array type, the result is the total number of bytes in the array."

C89 3.2.2.1

"Except when it is the operand of the sizeof operator or the unary & operator, or is a character string literal used to initialize an array of character type, or is a wide string literal used to initialize an array with element type compatible with wchar_t, an lvalue that has type ``array of type '' is converted to an expression that has type ``pointer to type '' that points to the initial member of the array object and is not an lvalue."

Additionally, here is a thread of Linus Torvalds pointing out even more of the confusing nature of arrays and sizeof in C:

https://lkml.org/lkml/2015/9/3/428


Additionally, here is a thread of Linus Torvalds pointing out even more of the confusing nature of arrays and sizeof in C:

I really like the idiom for passing sized arrays suggested at the end of that LKML thread[1]: pass them by reference!

  void func(int (*arr)[256])
  {
    printf("arr size: %ld\n", sizeof(*arr));
  }

  int main(void)
  {
    int array[256];
    func(&array);
  }
[1] https://lkml.org/lkml/2015/9/7/147


I doubt Torvalds telling everyone that sizeof was a function helped with this confusion.


The array->pointer "decay" (as the standard calls it) has 3 exceptions, of which two are when an array is the operand of "sizeof", and when it is the operand of "&". (The third involves a string initialiser, which is not relevant here.)

So your reasoning is not quite correct, it should really be that you think of

    sizeof( &array[0] )
as being

    sizeof( &(something) )
where "something" could be of any type T, and so the '&' operator yields "pointer-to-T", to which sizeof will yield the size of a pointer.


> and when it is the operand of "&"

Another slightly confusing aspect is that `&array` gives you a "pointer to array" (which has the same value as `&array[0]`, but is of a different type). Most importantly, it behaves differently in pointer arithmetic (the implied offset is the size of the array, rather than the size of its elements).


Fabien is hinting at the confusion: sizeof(&array[0]) != sizeof(array)

&array[0] and array decay to the same thing, the pointer to the first element if they are used in an expression. But sizeof gives a different result, because array+0 'decays' to a pointer, and array doesn't.




Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact

Search: