0

Please take a look at the minimal code example below. I've noticed a behavior in C that I cannot find an explanation for, so I decided to post a question here.

Case 1

The goal was to declare and initialize an array in main, and then pass it to function1. The trick was to then find the number of elements of that array in function1 without having to first calculate it in main, and then pass it as the argument. That did not work.

Case 2 and Case 3

Here, I calculate the number of elements in the array in main, and then pass it as the argument in function2. That works perfectly.

Question

My question is not necessarily why this process of calculating the number of elements in an array does not work in functions other than main; that kind of makes sense.

My understanding is that the array is nothing but the pointer to the first element (in this case double *). The size of such pointer (at least on my computer architecture) is 8 bytes. So, sizeof(a) = 8. This is also the same as size of any one of the elements (sizeof(a) == sizeof(a[0])). Thus, I will always get that numOfElements == 1.

My question is rather what makes main so special that it knows how to "properly" answer my query regarding sizeof(a). Particularly, since I had an array of 4 doubles, main will tell me that sizeof(a) == 32, which is exactly what I needed to calculate numOfElements.

Also, why is GCC giving me the warning? Does it know that I will not get the value I am actually looking for?

Thank you to anyone who advances my knowledge. I apologize if the answer is rather obvious. Perhaps, I am looking at this from a bit too abstract point of view than needed to analyze this behavior.

Code

#include <stdio.h>

void function1(double a[])
{
    int numOfElements = sizeof(a) / sizeof(a[0]);

    printf("\n ---> Size of array in function1: %d\n", sizeof(a));

    // Some operations...
}

void function2(double a[], int numOfElements)
{
    // Some operations...
}

int main()
{
    double a[] = {1.32, 2, 5.52, 9.99};
    
    // Case 1
    function1(a);

    // Case 2
    int numOfElements = sizeof(a) / sizeof(a[0]);
    function2(a, numOfElements);
    
    // Case 3 - a more compact version of Case 2
    function2(a, sizeof(a) / sizeof(a[0]));

    printf("\n ---> Size of array in main: %d\n", sizeof(a));
    
    return 0;
}

Output and Warning

enter image description here

Vladimir
  • 125
  • 5
  • 1
    `void function1(double a[])` is actually `void function1(double *a)` - therefore no size information is received via the argument – UnholySheep Jun 02 '22 at 15:23
  • There is a difference between arrays and pointers in C. Inside main, `a` is treated as an array. Inside functions, it's effectively a pointer. – Seva Alekseyev Jun 02 '22 at 15:25
  • 2
    Sorry, this is not "how do i get size of my array" question, OP already knows, The question is about why that happens in main and not in the called function. Voted to re-open, feel free to revert with a suitable dupe, as applicable. – Sourav Ghosh Jun 02 '22 at 15:25
  • 1
    the duplicate does not address why sizeof is not working with function parameters as well as how to get the size of an parameter array (spoiler: you can't because there are no such thing parameters of type array) – bolov Jun 02 '22 at 15:26

1 Answers1

2

It's not about main(), as long as you are not passing an array as function argument, you are okay.

In other words, arrays are not pointers and vice-versa. However, when an array is passed as a function argument, it decays to the pointer to the first element, so using sizeof on the received parameter inside the called function does not yield the expected result.

However, in the same function where the array is defined, it's still an array, and using sizeof returns the expected size. So, it's not specific about main(), it's about passing the array as function argument or not.

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261