Why struct assignment works with arrays in structs

Why after years of C programming am I having an existential language crisis about a mechanism I have used but never understood?

You always misunderstood arrays and now this has brought it to light :)

The actual rules are:

  1. Arrays are different to pointers; there is no "implied pointer" or anything in an array. The storage in memory for an array consists of exactly the cells with the array contents and nothing more.

  2. When you use the array's identifier in an expression, then the value of that expression is a (temporary) pointer to the array's first element. (With a handful of exceptions that I omit for brevity).

    2a. (in case this was unclear) Expressions have values , and the value of an expression does not require storage. For example in the code f(1 + 1), the value 2 is a value but it is not in an object and, conceptually, it is not stored anywhere. The pointer mentioned above is the same sort of value.

The reason you cannot write:

data2 = data;

is because Rule 2 kicks in , the value of the right-hand side is a pointer, and the assignment operation is not defined between an array and a pointer. (It wouldn't know how many units to copy).

The language designers could have added another exception to Rule 2 so that if the array is the sole right-hand operand of = then value conversion doesn't occur, and the array is assigned by value. That would be a consistent rule and the language would work. But they didn't.

The structure assignment does not trigger Rule 2 so the array is happily copied.

In fact they could have done away with Rule 2 entirely, and the language would still have worked. But then you would need to write puts(&s[0]); instead of puts(s); and so on. When designing C (incorporating BCPL which I think had a similar rule) , they opted to go for including Rule 2, presumably because the benefits appeared to outweigh the negatives at the time.


Assigning from one struct to another does an element-by-element copy of the struct's members. I think your problem is in overthinking the concept of an "element-by-element copy" operation. If you tried to do your own copy using the assignment operator on each individual element, then you would indeed run into the problem with not being able to copy the array. When you do a direct struct assignment, though, the compiler knows what code to emit to handle the internal array correctly. It's not simply syntactic sugar on top of using the assignment operator on each member.