1
char str1[ ] = "Hello" ; 
char str2[10] ; 
char *s = "Hey" ; 
char *q ;
str2 = str1 ; /* error */ 
q = s ; /* works */ 

Is is something inbuilt property in C or some reason is there? Why can you assign structures which contain arrays if you can't assign arrays?

kaushal sanadhya
  • 107
  • 1
  • 17
  • but structures can be assigned to another structure then why not array?I am still not getting my answer..!! – kaushal sanadhya Jan 29 '17 at 15:40
  • 2
    I'd be pretty confident that the structure assignment behaviour came later than the arrays outside the structure. You should really edit your question to add your puzzlement — though the answer remains "Yes; it is an in-built property of C that you cannot do plain array assignments". And even if the arrays are both inside structures, you can't assign one array (member) to another (array member) except as part of a structure assignment. – Jonathan Leffler Jan 29 '17 at 16:11

2 Answers2

8

There are two reasons you can't assign arrays:

  1. Because the designers of C were afraid it would be too inefficient.
  2. 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.

Steve Summit
  • 45,437
  • 7
  • 70
  • 103
  • Now if I try to redefine the value of string array then also it is not possible why? str a[]="kaushal"; a="kai"; not works....!! – kaushal sanadhya Jan 29 '17 at 15:55
  • 1
    @kaushalsanadhya You mean, if you try to assign one `char` array to another? I used `int` arrays in my answer, but the explanation applies to *all* arrays, of any type, `int`, `char`, `double`, or anything else. – Steve Summit Jan 29 '17 at 16:03
  • 1
    @kaushalsanadhya-- your first example of `str a[] = "kaushal"` is an _initialization_. The second example is an _assignment_, but `a` is an array type, and you can't assign to an array type. – ad absurdum Jan 29 '17 at 16:09
  • 1
    Note: with array-decays-to-pointer, any function receiving an "array" knows nothing of its size. Hence "array-asignment" (copying) cannot be determined by the compiler. (Note also: in the struct the array size is compile-time known hence can be copied.) – Paul Ogilvie Jan 29 '17 at 16:39
2

It is a historical property of C arrays, which is rooted in properties of arrays in B and BCPL languages.

C arrays are different from B/BCPL arrays specifically because C language introduced the concept of structs and wanted to makes struct types trivially copyable (and today you can assign struct types even with arrays inside). But in other respects C arrays were made to emulate B/BCPL arrays as closely as possible. This is what made C arrays generally non-copyable.

For more details you can read here: https://stackoverflow.com/a/38857777/187690

Community
  • 1
  • 1
AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765
  • Interesting read at the link to your other answer. Also interesting information at the link you provide there to Ritchie's [_The Development of the C Language_](https://www.bell-labs.com/usr/dmr/www/chist.html). I hope you don't mind that I added that link here in the comments. – ad absurdum Jan 30 '17 at 02:19