6

Is the following code safe, so long as I don't read any elements of the struct's array without setting it with a real value first? Thanks.

const int data_size = 5;

struct Testing
{
    int data[data_size];

    Testing(const int data[data_size])
    {
        std::copy(data, data + data_size, this->data);
    }
};

int main()
{
    int data[data_size];
    data[2] = 57;

    Testing t(data);

    t.data[1] = 93;
}
Neil Kirk
  • 21,327
  • 9
  • 53
  • 91
  • 2
    Not sure why you would want to do this, but it should be safe. Garbage in garbage out, but the garbage shouldn't fall out of the garbage can and stink up surrounding memory. – Michael Dorgan Mar 05 '13 at 18:43
  • 2
    With non trivially assignable types it is very likely unsafe, and definitely undefined behavior. With trivially assignable types, it is *probably* safe, under most conditions, but definitely still undefined behavior. – Benjamin Lindley Mar 05 '13 at 18:53
  • Hi Ben, I don't understand your comment. What do you mean trivially assignable? – Neil Kirk Mar 05 '13 at 20:21
  • @NeilKirk: To be trivially assignable means that assigning one object to another is equivalent to a bit-by-bit copy, something that is not the case with complex objects, like `std::string`. But it is the case with built-in types like `int`. – Benjamin Lindley Mar 05 '13 at 20:36

1 Answers1

9

std::copy is defined as doing *(result + n) = *(first + n) for each element in the sequence (§25.3.1). The value given by *(first + n) is an lvalue expression (§5.3.1/1), in your case referring to an uninitialized value. Since the assignment operator expects a prvalue as it's right operand (this is ill-specified), this will result in lvalue-to-rvalue conversion. Lvalue-to-rvalue conversion on an expression referring to an uninitialized value is undefined behaviour (§4.1):

If the object to which the glvalue refers is not an object of type T and is not an object of a type derived from T, or if the object is uninitialized, a program that necessitates this conversion has undefined behavior.

So your code has undefined behaviour. The solution is of course to initialize the elements of the array (perhaps with int data[data_size] = {};).

Community
  • 1
  • 1
Joseph Mansfield
  • 108,238
  • 20
  • 242
  • 324