This is because arrays decay into pointers to their first elements when passed to a function.
There is no run-time storage of the length associated with the array, so this won't work. Basically for a function argument, a type such as int a[] is equivalent with int *a, i.e. it's just a pointer.
It's best to simply always pass a length when you need to pass arrays to functions, and you can never have a function like your len(). The exception is of course if you store the length yourself in the pointed-at data, like strings do with the terminator character.
As a stylistic point, this code in main():
printf("%d\n", sizeof(a)/sizeof(int));
is in my opinion better written as:
printf("%zu\n", sizeof a / sizeof *a);
With the following noteworthy changes:
- The result of
sizeof has type size_t, which is not an int. It's correctly printed by the format specifier %zu.
- Note that
sizeof is not a function, so the parenthesis are not needed in most cases.
- Prefer to reference to variables, rather than repeating type names that may or may not be associated with the variables.
sizeof *a means "the size of the value that a points at".
- Also note that according to C's operator precedence rules,
sizeof binds tighter than /, so the expression really means (sizeof a) / (sizeof *a), which is the desired result.