Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't a modifiable lvalue have an array type?

From C11 standard (§6.3.2.1 Lvalues, arrays, and function designators):

A modifiable lvalue is an lvalue that does not have array type, does not have an incomplete type, does not have a const-qualified type, and if it is a structure or union, does not have any member (including, recursively, any member or element of all contained aggregates or unions) with a const-qualified type.

From C in a Nutshell:

A modifiable lvalue is an lvalue that is not declared as a const -qualified “Type Qualifiers” on page 180), and that does not have an array type.

What is the reason that a modifiable lvalue can't have an array type?

Is an object of an array type always implicitly const?

like image 880
Tim Avatar asked Aug 13 '17 00:08

Tim


People also ask

Can an array be an lvalue?

An array can be an lvalue (but not a modifiable lvalue), and an "array name" (identifier) is always an lvalue.

How can an array be an lvalue if you can't assign to it?

The answer to this question is no, because an array is composed of several separate array elements that cannot be treated as a whole for assignment purposes. The following statement is therefore illegal: int x, y; x = y; Additionally, you might want to copy the whole array all at once.

Is an array changeable?

If you create an array by initializing its values directly, the size will be the number of elements in it. Thus the size of the array is determined at the time of its creation or, initialization once it is done you cannot change the size of the array.

What is a modifiable lvalue?

A modifiable lvalue is addressable (can be the operand of unary &) and assignable (can be the left operand of =). A non-modifiable lvalue is addressable, but not assignable. An rvalue is neither addressable nor assignable.


1 Answers

The designers of the C language decided that it should not be possible to assign arrays by value. At the time this seemed a sensible decision (early 1970s) - memory and processor speed were very limited and they considered that having a = b; make a and b both refer to the same array was something that would be a much more common intent than having a = b; be used to copy the contents of one array to another.

In fact this was already common usage: in the B programming language (precursor to C), the equivalent of int a[10]; actually meant to allocate both a pointer, and a block of 10 ints, and point the pointer to the block of 10 ints. You could actually make an array "point" somewhere else in B.

C changed the meaning of an array definition that it only allocates the block of ints; and added "The Rule": when you use the array's name in an assignment expression (and most other expressions) the array is implicitly converted to a pointer to the first element. So, if a is a pointer and b is an array, then you can still write a = b; to make a behave like an alias for b. Although you can no longer have a = b; where a is an array.

In the first ANSI C standard in 1989 they added the ability to copy structs by value (this had existed in some compilers previously but wasn't universal), with the corollary that if the struct contains an array then the array gets copied by value. But it was far too late to go back and change the meaning of a = b; to copy arrays by value, too much code was written that already depends on The Rule.

Reference: The Development of the C Language - Dennis M. Ritchie

like image 65
M.M Avatar answered Oct 23 '22 21:10

M.M