Arrays are treated differently than other types; you cannot pass an array "by value" in C.
Online C99 standard (draft n1256), section 6.3.2.1, "Lvalues, arrays, and function designators", paragraph 3:
Except when it is the operand of the sizeof operator or the unary & operator, or is a
string literal used to initialize an array, an expression that has type ‘‘array of type’’ is
converted to an expression with type ‘‘pointer to type’’ that points to the initial element of
the array object and is not an lvalue. If the array object has register storage class, the
behavior is undefined.
In the call
foo(buf);
the array expression buf
is not the operand of sizeof
or &
, nor is it a string literal being used to initialize an array, so it is implicitly converted ("decays") from type "10-element array of char" to "pointer to char", and the address of the first element is passed to foo. Therefore, anything you do to buf
in foo()
will be reflected in the buf
array in main()
. Because of how array subscripting is defined, you can use a subscript operator on a pointer type so it looks like you're working with an array type, but you're not.
In the context of a function parameter declaration, T a[]
and T a[N]
are synonymous with T *a
, but this is only case where that is true.