This code doesn't work:
int main() {
int arr1[10];
int arr2[10];
arr2 = arr1;
return 0;
}
But this works:
struct foo {
int arr[10];
};
int main() {
struct foo f1;
struct foo f2;
f2 = f1;
return 0;
}
But in my opinion, they do the same thing: just copy an array to another array.
A consequence of the historical development of C is that you cannot refer to arrays directly.
In arr2 = arr1;
, both arr2
and arr1
name an array. But there is a rule in C that says when an array is used in an expression, it is automatically converted to a pointer to its first element, with certain exeptions.1 C is certainly capable of copying one array to another, as with memcpy(arr2, arr1, sizeof arr2);
. The problem is there is simply no way of referring to the array in an assignment statement.
This automatic conversion of arrays was made to provide convenience for accessing elements of array and working with arrays in the ways that were used when the C language was first being developed. It was not anticipated there would be a need to refer to the entire array as a whole object, and nothing was built into the language for that. (Even today, it is not necessary—there are few operations we want perform on an array as a single object, other than copying it.)
Early C implementations also would not let you copy structures by assignment. C was a fairly basic language, providing just simple operations, and copying entire structures would have been a fancy thing. Later, the ability to copy structures was added.
In f2 = f1;
, f2
and f1
refer to the structures, and there is no rule about them being automatically converted to anything, as there is for the arrays.
So the problem is simply a matter of being able to express the desired operation.
1 The rule is in C 2018 6.3.2.1 3, and the exceptions are when the array is the operand of sizeof
or unary &
or is a string literal that is used to initialize an array (as in char x[] = "abc";
—"abc"
is a string literal, which is an array).
Here
int main() {
int arr1[10];
int arr2[10];
arr2 = arr1;
return 0;
}
arr2 = arr1;
doesn't work because arr2
is array and array name itself base address i.e const & you can't change that address i.e arr2
can not point to any other address. By doing arr2 = arr1;
you are trying to change arr2
base address which is not possible. While here
f2 = f1; /* structure member copy, f2 is structure variable and it can assigned with another structure variable f1 */
f2
is a structure variable and by doing f2 = f1;
the f1
members gets copied into f2
.
But in my opinion, they do the same thing: just copy an array to another array.
yes, but compiler won't allow to perform first one arr2 = arr1
due to the fact that you can't change the base address of arr2
while in another f2=f1
f1
structure variable members gets copied to f2
member by member and since f2
is not an array, its possible.
Paragraph from 6.3.2.1 Lvalues, arrays, and function designators
- When an object is said to have a particular type, the type is specified by the lvalue used to designate the object. *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.
Here
arr2 = arr1;
the lvalue operand arr2
is not modifiable.
Another para about the same which tells about decaying
- Except when it is the operand of the sizeof operator, the _Alignof 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 you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With