This followup is about C, but I've kept the wide cross-post for
now to make sure it's seen. Please consider redirecting further
followups to comp.lang.c if you want to discuss this further.
If you don't care about C, feel free to stop reading now; there is
no Fortran, PL/I, or numerical analysis content.
Er, no. While I agree that I was over-simplifying, you have seriously
misunderstood C.
It is NOT just when they are parameters, but any
time that they are used as values - there is no such thing as a
string, array or function value in C.
I accept that there are such things as string, array or function
declarations, and array or function types - but you can't do anything
with objects declared as such without converting them to pointers.
Except for sizeof, of course, but that really operates on types.
Seriously. Look at the standard in depth, and see.
I have looked at the standard in depth, and no, I haven't
misunderstood it.
A "string" is, by definition, "a contiguous sequence of characters
terminated by and including the first null character" (C99 7.1.1p1).
It's a data *layout*, not a data type. An array object may *contain*
a string at run time.
There's a tight relationship between arrays and pointers in C, but that
relationship absolutely is not identify. They are very different
things. An array type "describes a contiguously allocated nonempty set
of objects with a particular member object type, called the element
type" (C99 6.2.5p20); a pointer type "describes an object whose value
provides a reference to an entity of the referenced type" (same
paragraph).
There are several rules in C that tend to cause confusion in this area.
First, a parameter declaration of array type, such as
int foo(char arr[]);
is really a pointer declaration:
int foo(char *arr);
This isn't a run-time conversion, it's a compile-time adjustment.
For details, see C99 6.7.5.2p7.
Second, any expression of array type is implicitly converted to a
pointer to the array object's first element, with three exceptions.
This is a conversion, not an equivalence; it's an entirely separate
rule from the one for parameters, and applies in all expression
contexts. The exceptions are when the array expression is the
argument of a sizeof operator (sizeof arr yields the size of the
array, not the size of a pointer to the first element of the arrray),
when it's the argument of a unary "&" (address) operator (&arr yields
the address of the entire array, not of its first element; they're of
different types), and when it's a string literal in an initializer
used to initialize an object of array type (``char arr[10] = "hello";''
doesn't convert "hello" to an address). C99 6.3.2.1p3.
Section 6 of the comp.lang.c FAQ, <
http://www.c-faq.com/> does a very
good job of explaining the relationship between C pointers and C arrays.
Similar rules apply to expressions of function type; see C99
6.3.2.1p4. Note that sizeof func, if func is a function name,
doesn't cause a conversion to pointer type, but in this case the
result is an error (constraint violation), since sizeof cannot
be applied to a function. A function call (which can be thought
of as an applicaton of the function call operator) requires a
pointer-to-function as its prefix. In most cases, this will be a
function name (an expression of function type) implicitly converted
to a pointer-to-function type.
Are there a string values? Maybe. There's no string type, but an array
object can contain a string. I don't think the standard uses the
term "string value".
Are there function values? No. There are expressions of function
type, but in most contexts they're immediately converted to pointers.
Are there array values? Absolutely. A "value" is the "precise
meaning of the contents of an object when interpreted as having a
specific type" (C99 3.17). For an array object, the value consists
of the values of all its elements. (Note that the standard's
definition of "value" is incomplete; it doesn't cover the value of
an expression, an unfortunate oversight IMHO.)
As I said, arrays and functions are almost always manipulated via
pointers (for arrays, it's usually a pointer to the first element
rather than a pointer to the entire array). Neither array types nor
pointer types are first-class, as they are in some other languages.
But they are types, and they are most definitely distinct from
pointer types (though the language sometimes seems to conspire to
obscure that distinction).
For example:
void print(char param[]) {
puts(param);
}
/* ... */
char s[6] = "Hello";
print(s);
The declaration of "param" is really a pointer declaration,
though the syntax makes it look like an array declaration; I could
equivalently have written ``void print(char *param)''. In the call
to print(), it *looks* like an array value is being passed to a
function that takes an array argument -- but in fact what's being
passed is a pointer to the array's first element (and the function
finds the end of the string by looking for the terminating null
character) -- or rather the puts function does that). Nevertheless,
there is a real array object called "s", and it contains an array
value consisting of 6 char values ('H', 'e', 'l', 'l', 'o', '\0').
And in the calls themselves, ``puts'' and ``print'' are expressions
of function type (the names of functions), but they're implicitly
converted to values of pointer-to-function type.
Strings are not pointers. Arrays are not pointers. Functions are not
pointers.