There are two reasons you can't assign arrays:
- Because the designers of C were afraid it would be too inefficient.
- Because by the rules of C, if you tried to say "array1 = array2", it would actually end up being "array1 = pointer-to-array2", and that makes even less sense.
Now, some more explanation on both of these points.
(1) It was one of the original goals of C that just about all of its built-in operations translate to one or two machine instructions. Anything complicated or expensive was typically going to require an explicit function call. So if you want to copy one array to another, you have to explicitly write
memcpy(array1, array2, sizeof(array2));
The compiler is not willing to generate this potentially-expensive code for you. (Yes, I know, structure assignment is a contradiction to this rule. More on that later.)
(2) It is a fundamental rule of C (the so-called "equivalence between arrays and pointers") that, with a handful of exceptions, when you mention an array in an expression, you automatically get a pointer to the array's first element. That is, if you say
int a[10];
int *p;
p = a;
the assignment "p = a
" is not a type mismatch, and it does exactly the same thing as if you had written
p = &a[0];
That is, p
receives a pointer to a
's first element.
So if you tried to assign one array to another:
int a1[10], a2[10];
a1 = a2; /* wrong */
it would be as if you had said
a1 = &a2[0]; /* also wrong */
and this doesn't make any sense.
Finally, what about structures? You can assign one struct to another, and this typically involves copying N bytes, just the kind of potentially-expensive operation I claimed C wasn't willing to do when all you typed was one assignment operator '=
'. This is indeed an exception, a contradiction; it's somewhat of an internal inconsistency in the C language. Here's how it came about.
I'm pretty sure the very first versions of C (that is, the very first versions of Ritchie's original C compiler for the PDP-11) didn't have structs at all. Then, when structs were first added, they had a limitation: you couldn't assign them, or pass them to functions, or return them from functions. (These limitations made structs less useful, but they made sense in the context of keeping the compiler simple, and not having it generate expensive code behind your back.) Then, still later, the limitations were removed: struct assigning (and passing and returning) were all added. (This was all a very long time ago by now, during the dawn of C. If I remember correctly, the first editions of the K&R book said that the restrictions were to be "lifted soon", and that a version of the compiler that supported them came out at about the same time the book hit the bookstores.)
If you want to make apologies for the contradiction, you can point out that structs are often small (meaning that they can often be assigned using just a few instructions), whereas arrays can be arbitrarily large. But, again, even if you wanted to somehow extend the language by adding array assignment, you couldn't, because of reason #2.
It's often said that array types are "second-class citizens" in C, and what this means is precisely that you can't assign them, or pass or return them to or from functions. Moreover, this can never be fixed (there can be no emancipation of their second-class status) because there's already a definition of what happens when you try to assign an array, or pass it to a function, or return it from a function: in all cases you end up operating on just a pointer to the array's first element, instead.
(I think there have been attempts over the years to add array assignment as an extension, using some special syntax to "turn off" the pointer equivalence rule. I can't remember how they worked, but I don't think any of them ever caught on, much less became standard.)
Two footnotes:
[1] Since you can assign structures, you can trick the compiler into doing array assignment for you by wrapping your array up in a structure. For example:
struct array_as_struct { int a[10]; };
struct array_as_struct s1, s2;
s1.a[0] = 10;
s1.a[1] = 20;
s2 = s1;
This is perfectly legal; you're absolutely allowed to get away with this "trick"; the rule that you can assign structures definitely applies even if the structure happens to contain an array.
[2] In the old days, the fact that you couldn't pass structures to functions was one of the reasons that library functions like asctime
accepted pointers (and that functions like localtime
returned them). And the definitions of those functions persist to this day.