6

OK. We know the following code cannot be compiled.

char source[1024];
char dest[1024];
// Fail. Use memcpy(dest, source, sizeof(source)); instead.
dest = source;

But, the following code can be compiled and behave correctly.

class A {
    char data[1024];
};
A source;
B dest;
dest = source;

I was wondering, in operator assignment function, is array will be memcpy implicitly?

The following are the complete test code.


#include <cstdio>
#include <memory>

class A {
public:
    char data[1024];
};

int main() {
    {
        A source;
        A dest;

        // Initialization
        char *data = "hello world";
        memcpy (source.data, data, strlen(data) + 1);

        printf ("source.data = %s\n", source.data);
        printf ("address source.data = %x\n", source.data);

        // Works! Does this in the operator assignment function, memcpy is
        // being performed implicitly on array.
        dest = source;

        printf ("dest.data = %s\n", dest.data);
        printf ("address dest.data = %x\n", dest.data);
    }

    {
        char source[1024];
        char dest[1024];

        // Initialization
        char *data = "hello world";
        memcpy (source, data, strlen(data) + 1);

        printf ("source = %s\n", source);
        printf ("address source = %x\n", source);

        // '=' : left operand must be l-value
        // dest = source;
        // Works with memcpy.
        memcpy(dest, source, sizeof(source));

        printf ("dest = %s\n", dest);
        printf ("address dest = %x\n", dest);
    }

    getchar();
}

//RESULT :
//source.data = hello world
//address source.data = 12fb60
//dest.data = hello world
//address dest.data = 12f758
//source = hello world
//address source = 12f344
//dest = hello world
//address dest = 12ef3c
Cheok Yan Cheng
  • 47,586
  • 132
  • 466
  • 875
  • There was a lot of discussion about why this is the case in [Why does C++ support memberwise assignment of arrays within structs but not generally?](http://stackoverflow.com/questions/3437110/why-does-c-support-memberwise-assignment-of-arrays-within-structs-but-not-gene) – James McNellis Oct 22 '10 at 02:55

3 Answers3

9

Does this quote from the Standard help? It is quiet self explanatory

Sorry, removed my earlier answer which was related to copy constructor and not copy assignment operator.

$12.8/30-

The implicitly-defined copy assignment operator for a non-union class X performs memberwise copy 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. Each subobject is assigned in the manner appropriate to its type:

— if the subobject is of class type, the copy assignment operator for the class is used (as if by explicit qualification; that is, ignoring any possible virtual overriding functions in more derived classes);

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

— if the subobject is of scalar type, the built-in assignment operator is used.

Chubsdad
  • 24,777
  • 4
  • 73
  • 129
4

operator=, if not explicitly implemented, performs a memberwise copy of the class's contents. For your encapsulated array this will work but in general care is needed to ensure proper deep copying of the class's data.

Steve Townsend
  • 53,498
  • 9
  • 91
  • 140
  • note that it is not bitwise copy if the member has assignment-op. – YeenFei Oct 22 '10 at 02:58
  • 2
    No. It performs a member-wise copy. This is necessary since nested types may have their own operator=() at any depth in the nesting hierarchy. Their operator=() could have any number of side-effects outside of the range of bits that a bitwise copy would affect. These side-effects are guaranteed to happen. So, no, the copy is not bitwise. – Eric Towers Oct 22 '10 at 04:02
  • @Eric - thanks, updated the text and upvoted alternate answer – Steve Townsend Oct 22 '10 at 10:23
2

compiler generated copy-ctor / assignment-op is bitwise-copy if no copy-ctor / assignment-op found for the child elements.

Edit:
Here is the modified test case showing the concept.

#include <cstdio>
#include <memory>

class someElement
{
public:
    someElement() : theData(0) {}
    // Intentionally copy-edit
    someElement(const someElement& src) : theData(src.theData + 1) {}
    ~someElement(){}

    someElement& operator=(const someElement& rhs)
    {
        theData = rhs.theData - 1;
        return *this;
    }

    char    theData;
};

class A {
public:
    someElement data[1024];
};

int main() {
    {
        A source;
        A dest;

        // Initialization
        char *data = "hello world";
        memcpy (source.data, data, strlen(data) + 1);

        printf ("source.data = %s\n", source.data);
        printf ("address source.data = %x\n", source.data);

        // Works! Does this in the operator assignment function, memcpy is
        // being performed implicitly on array.
        dest = source;

        printf ("dest.data = %s\n", dest.data);
        printf ("address dest.data = %x\n", dest.data);
    }

    {
        someElement source[1024];
        someElement dest[1024];

        // Initialization
        char *data = "hello world";
        memcpy (source, data, strlen(data) + 1);

        printf ("source = %s\n", source);
        printf ("address source = %x\n", source);

        // '=' : left operand must be l-value
        // dest = source;
        // Works with memcpy.
        memcpy(dest, source, sizeof(source));

        printf ("dest = %s\n", dest);
        printf ("address dest = %x\n", dest);
    }

    getchar();
}
YeenFei
  • 3,180
  • 18
  • 26