sizeof behaving unexpectedly

前端 未结 4 1031
再見小時候
再見小時候 2021-01-04 09:02

Consider the following code:

  #include 
  int main(void)
  {
    int a[10];
    printf(\"%d\",(int)sizeof(a)); //prints 10*sizeof(int) (40 on         


        
相关标签:
4条回答
  • 2021-01-04 09:16

    Nope, in the second case the argument is interpreted as an int* pointer which happens to also have size equal to 4 on your machine.

    0 讨论(0)
  • 2021-01-04 09:30

    (a-3) has type int*, and it prints you sizeof(int*) which is 4 on your platform.

    And note that sizeof() is no longer compile-time constant in C99 (due to variadic-length arrays).

    0 讨论(0)
  • 2021-01-04 09:30

    sizeof() returns the size of a type, so the type is what's important.

    It also shouldn't be printed with %d. At the very least, explicitly cast it to unsigned long or unsigned long long and use the appropriate format specifier. When teaching C, I had a student get the wrong answer by printing size_t with %d as the textbook mistakenly said to do.

    Anyway, a is an array type. In C, array types decay to pointer types if you do almost anything with them or sneeze loudly, so almost anything you do to a will yield a pointer type. As you've found out, adding or subtracting a number will decay. (After all, an array can't be used in arithmetic, but a pointer can.)

    0 讨论(0)
  • 2021-01-04 09:31

    The sizeof operator doesn't evaluate its argument, it only looks at the type of its operand.

    Let's say you have an array a with type "array [N] of type T". Then, in most cases, the type of the name a is "pointer to T" (T *), and the value of the pointer is the address of the first element of the array (&a[0]). That is, the name of an array "decays" to a pointer to its first element. The "decaying" doesn't happen in the following cases:

    • when a is used with the address-of (&) operator,
    • in the initialization of a (it is illegal to assign to arrays in C), and
    • when a is the operand of the sizeof operator.

    So, sizeof a gives you N times sizeof(T).

    When you do sizeof(a-3), the type of the operand to sizeof is determined by the expression a-3. Since a in a-3 is used in a value context (i.e., none of the three contexts above), its type is "pointer to int", and the name a decays to a pointer to a[0]. As such, calculating a-3 is undefined behavior, but since sizeof doesn't evaluate its argument, a-3 is used only to determine the type of the operand, so the code is OK (see the first link above for more).

    From the above, sizeof(a-3) is equivalent to sizeof(int *), which is 4 on your computer.

    The "conversion" is due to the subtraction operator. You can see a similar, and perhaps more surprising, result with the comma operator:

    printf("%zu\n", sizeof(1, a));
    

    will also print sizeof(int *), because of the comma operator resulting in a getting used in a value context.

    0 讨论(0)
提交回复
热议问题