0

What is the difference between the two array assignments, one inside a struct and one outside a struct?

struct A
{
   char s[4];
};

int main(int argc, char *argv[])
{
   char s[4];
   char d[4];

   d = s; // 'invalid array assignment'

   A a, b;
   b = a; // compiles without problems

   return 0;
}

The default operator = is supposed to invoke member-by-member assignment operators. If so, then there should exist an array assignment operator, but the compiler does not want to invoke it explicitly. Why?

Enigma
  • 1,247
  • 3
  • 20
  • 51
bkxp
  • 1,115
  • 1
  • 12
  • 20
  • Your "indirect array assignment" is a structure assignment, and regularly used for returning fixed-arrays from functions and passing said structures as value-params. `a.s = b.s` would obviously likewise fail. – WhozCraig Jan 22 '15 at 15:04
  • 3
    Because C++ has its crazy side - the craziness here is that arrays are not first-class citizens of the language (e.g. they are not copyable and usually decay to pointers), and so structure copying has to have a special rule that says that array members are copied element-wise. If it weren't like this and arrays were like any other type, the structure copying rules would just say "all members are copied". – Joseph Mansfield Jan 22 '15 at 15:08
  • Also relevant: [Why array type object is not modifiable?](http://stackoverflow.com/q/17687429/2069064) – Barry Jan 22 '15 at 15:16

2 Answers2

1

I think this is why... Struct is a class object and there is this special rule for assignment of member its an array, not for an array itself (c++14 draft):

12.8 Copying and moving class objects

12.8.28. The implicitly-defined copy/move assignment operator for a non-union class X performs memberwise copy- /move assignment of its subobjects. The direct base classes of X are assigned first, in the order of their declaration in the base-specifier-list, and then the immediate non-static data members of X are assigned, in the order in which they were declared in the class definition. Let x be either the parameter of the function or, for the move operator, an xvalue referring to the parameter. Each subobject is assigned in the manner appropriate to its type:

  1. — if the subobject is an array, each element is assigned, in the manner appropriate to the element type;

So the copy procedure is not defined for an array (because it's an unmodifiable variable type), but for a member type that is an array. There is no definition for implicit operator= for an array.

luk32
  • 15,812
  • 38
  • 62
-2

The value of an array name (e.g., s) is the starting address of the array. Once the array is allocated in memory, that address should be fixed. d = s is saying to assign the starting address of s[4] to d[4], which obviously can't be done.

A simple structure like yours is just a chuck of bits. In your case, an instance of A occupies 4 bytes. When you do a = b, it copies the bits of b to that of a.

To illustrate the difference, I don't think you can do a.s = b.s. You can try.

Neo1989
  • 285
  • 3
  • 14