Topic: Can you copy-construct an array?


Author: garry@ithaca.com (Garry Wiegand)
Date: Thu, 2 Dec 1993 22:30:49 GMT
Raw View
Given this code, which basically wants to copy-construct a structure
that includes an array:

    struct foo {
        int     a, b, c[10];
    //  foo (foo const & input) : a(1), b(input.b), c(input.c) {}
    };

    void copyit (foo const & source) {
        foo     dest(source);
    }

all compilers I have access to (except gcc) compile fine when the
indicated line is commented out. When the '//' is removed, no
compiler I have access to is able to compile it. The error messages
from the cfront-based compilers look like:

    CC: "q.cxx", line 1: error: initializer for foo::c of type  int [50] (1098)

and I can't say as I disagree with the message, although I'm a
little mystified as to why it must be an error. As it is, a
conforming C++ compiler is able to generate a default
copy-constructor that includes an array, but I am apparently not
permitted to write an explicit copy-constructor that includes an
array. No fair!

One alternative is to substitute an assignment loop for the copy-
construct. The void constructor would be applied to the array
elements. But in the real world of our application it can easily
happen that there is no void constructor or that the void
constructor/the assignment op are relatively expensive to call.

Another alternative is to write
    struct foo {
        int     a, b, c[10];
        foo (foo const & input) : a(1), b(input.b),
         c[0](input.c[0]), c[1](input.c[1]), c[2](input.c[2]),
         c[3](input.c[3]), c[4](input.c[4]), c[5](input.c[5]),
          c[6](input.c[6]), c[7](input.c[7]), c[8](input.c[8]),
         c[9](input.c[9]) {}
    };

But this blows up with a bang on all the compilers.

Finally, I can break the fingers of C++ by, for example, hiding the
array behind a void pointer and using malloc plus explicit
per-element constructor calls to get it built. I would consider this
alternative unfortunate.

Is my analysis correct? I can't find anything in the ARM which has
much to do with copy-construction of arrays.

garry

--
Garry Wiegand --- garry@ithaca.com --- Ithaca Software, Alameda, California




Author: pkt@lpi.liant.com (Scott Turner)
Date: Fri, 3 Dec 1993 16:21:37 GMT
Raw View
In article <CHFIJE.IIL@ithaca.com>, garry@ithaca.com (Garry Wiegand) wrote:

> Given this code, which basically wants to copy-construct a structure
> that includes an array:
>
>     struct foo {
>         int     a, b, c[10];
>     //  foo (foo const & input) : a(1), b(input.b), c(input.c) {}
>     };
>
>     void copyit (foo const & source) {
>         foo     dest(source);
>     }
>
> all compilers I have access to (except gcc) compile fine when the
> indicated line is commented out. When the '//' is removed, no
> compiler I have access to is able to compile it.

LPI C++ compiles it to the object code you would expect,
but gives a diagnostic

    An array expression may not be used as an array in this context,
    because it is implicitly converted to a pointer to the array's
    first element.

Because of this implicit conversion, such code is not valid C++.
I've considered crusading to improve the status of arrays in C++,
but it's really impossible to "fix" them properly because

    int foo(Type[100]);

must forever declare a function with a *pointer* parameter.  Otherwise
lots of code would be broken.  And people make the point that if you
want to do nice things with arrays, you should probably use a nice
array template that does automatic bounds checking, etc.

Nevertheless, IMO no harm would be done if that implicit conversion
were removed in cases where the context demands an array.  Such an
extension would make your example valid.