There are actually two related but independent rules in play here.
One is that an expression of array type is, in most contexts, implicitly converted (at compile time) into a pointer to (i.e., the address of) the first element of the array. The exceptions are when it's the operand of sizeof
, when it's the operand of unary &
, and when it's a string literal in an initializer used to initialize an array object.
The other is that a function parameter declared to be of an array type is really of a pointer type -- and if the array type includes a length, that length is silently ignored. This is the rule that causes the behavior you're seeing.
Strongly recommended reading: Section 6 of the comp.lang.c FAQ.
EDIT : Your program has several errors that would prevent it from compiling, which means you couldn't have seen the results you say you're seeing. You apparently re-typed the program when posting it here. Instead, you should copy-and-paste the exact code as you fed it to the compiler.
Here's a corrected version of your code, with a bit of commentary added.
#include <stdio.h> /* required for printf */
void foo(const char data[10]) /* NOTE: The 10 is quietly ignored */
{
char copy[10];
/* syntax, [10] follows "copy", not "char" */
const char copy1[10]; // = {};
/* as above, and standard C disallows empty initializer */
printf("%d", (int)sizeof copy); // prints 10, as expected
printf("%d", (int)sizeof copy1); // prints 10, as expected
printf("%d", (int)sizeof data); // prints 4 (sizeof (char*), as expected
/*
* "%i" or "%d" requires an int argument; sizeof yields size_t.
* You need to convert the result.
* "%d" is more common and idiomatic than the equivalent "%i"
* When sizeof is applied to an expression, no parentheses are needed
* (it's an operator, not a function
*/
}