Ben Bacarisse <
ben.u...@bsb.me.uk> writes:
> Keith Thompson <
ks...@mib.org> writes:
>> Chad <
cda...@gmail.com> writes:
>> [...]
>>> What about the following...
>>>
>>>
http://67.40.109.61/torek/c/expr.html
>>>
>>> And I quote..
>>>
>>> "Array objects have a special, fundamental rule in C. This rule is
>>> essentially arbitrary, and simply must be memorized. It falls out
>>> from a key fact: C does not have array values. (There is one
>>> exception to this, which I will save for later.) C does have array
>>> objects -- just the values are missing. For instance, int a[5];
>>> declares an ordinary array containing five ints. Logically, the
>>> ‘value’ of this array ought to be the five int values stored in that
>>> array -- but it is not. Instead, the ‘value’ of the array is a
>>> pointer to the first element of that array. "
>>>
>>> The point being that, if I understand correctly, C does not have
>>> 'array of integers'. Instead, at least according to the former
>>> comp.lang.c regular on here, the language has 'array objects'.
>>
>> I find the quoted text misleading at best.
>>
>> C does have array values; it just doesn't let you manipulate them
>> directly in most cases. The standard's definition of the word
>> "value" (C99 3.17) is "precise meaning of the contents of an object
>> when interpreted as having a specific type". Nothing in that
>> definition excludes arrays.
>
> That definition is effectively useless. Functions, for example, are
> said to return values. What object is being interpreted to get the
> value returned by afunction? In the expression '1 + 1.0' something (it
> is a value?) of type int is converted to a value of type double by the
> usual arithmetic conversions, but there are no objects involved here.
> The same goes for (int)1.0.
The problem with the definition is that it's incomplete (like a
number of other definitions in the standard). What it describes
is certainly an *example* of a value, but surely the evaluation of
an expression also results in a *value*. Indeed the definition of
"expression" (6.5p1) is "a sequence of operators and operands that
specifies computation of a value, or that designates an object
or a function, or that generates side effects, or that performs a
combination thereof". (Which, taken literally, implies that 42 isn't
an expression, since it contains neither operators nor operands.)
But what I conclude from that definition is that any object with
valid contents has a "value", which is the meaning of its contents
when interpreted as having a specific type.
> Some operators seem to try hard to avoid talking about values. For
> example, '1 + 2' has a result but not a value. Others talk about "the
> value of the result", further complicating matters.
>
>> Given:
>>
>> int arr[5];
>>
>> the value of arr consists of the values of its 5 elements,
>> interpreted as having type "int[5]". When you store something
>> into an array object, that object has a value, and that value is
>> an array value.
>
> I disagree, though I expect to regret it! The footnote on 6.3.2.1 p1
> seems to make it clear that the unqualified term "value" means what
> other languages call an rvalue and 'arr' is not one of those.
The footnote says:
What is sometimes called "rvalue" is in this International
Standard described as the "value of an expression".
That's not the unqualified term; it's the value *of an expression*.
The only consistent interpretation I can come up with is:
The Standard's definition of "value" is incomplete.
Any object in which something valid has been stored (handwaving meant to
exclude trap representations and perhaps indeterminate values) has a
"value", which is the "precise meaning of the contents of an object
when interpreted as having a specific type".
Any expression which (a) is not of function type, (b) is not an
lvalue, and (c) is not of void type yields a *value* when it's
evaluated. This is not covered by the definition of "value" in 3.17,
but it is covered by the definition of "expression" in 6.5p1.
6.3.2.1p2 ties these together:
Except when it is the operand of the sizeof operator, the unary &
operator, the ++ operator, the -- operator, or the left operand
of the . operator or an assignment operator, an lvalue that does
not have array type is converted to the value stored in the
designated object (and is no longer an lvalue). If the lvalue
has qualified type, the value has the unqualified version of
the type of the lvalue; otherwise, the value has the type of
the lvalue. If the lvalue has an incomplete type and does not
have array type, the behavior is undefined.
This says that evaluating the name of an object yields the value of
the object (and likewise for more complex lvalues). You can't get
the value of an array object by evaluating its name. That doesn't,
IMHO, imply that the array object doesn't have a value, and in fact
the incomplete definition of "value" in 3.17 implies that an array
object *does* have a value.
I'd be happier if the standard stated this more directly.
[...]
> The sub-expression 'arr' is an lvalue. I.e. it is an kind of
> /expression/, not a particular kind of /value/. When used on its own,
> this lvalue, this expression, is converted to a pointer to the array.
> At no point is there a value (read rvalue) in existence; the expression
> is converted, not its value.
Array values do not show up during expression evaluation. But (I
argue) they do exist in array objects.
[...]
> I think the use of the term "designate" both in 6.3.2.1 p1 and in the
> description of the & operator is deliberate and significant. It means
> that lvalue expressions of array type never need to be said to have a
> value.
I agree with that.