0

We have a large code base mainly written in C. We do a lot of numerical linear algebra.

In C we use double*, with length 3 to model a 3d vector.

In C++ we use std:array<double,3> to model a 3d vector.

We have a small template library to overload a lot of operators, such as

template <class T, size_t N>
std::array<T, N> operator+(const std::array<T, N> &array1, const std::array<T, N> &array2) {
    std::array<T, N> a;
    for (size_t i = 0; i < N; i++) {
        a[i] = array1[i] + array2[i];
    }
    return a;
}

The problem comes, when we need to go from C to C++ (the other way around is no problem, since we can use the .data() method to access the aligned memory). I do not like to make a copy of each c-like 3d vector, because this would be numerically expensive.

Can I treat a pod array as a std::array or is there a way of initializing an std::array in a way that no new memory is allocated, but the memory from the pod array is used?

I am thinking about using gsl::span from the guideline support library, but I wonder if there is a better solution.

1
  • Is the C variant an array (double[3]) or dynamically allocated (malloc(3*sizeof(double))? You might want to take a look at array_view in the first case. Commented Feb 16, 2018 at 9:33

1 Answer 1

-2

You can simply cast:

double* c_array; // assign to whatever you like, length 3 or more
auto cpp_array = reinterpret_cast<std:array<double,3>*>(c_array);

This works because std::array is definitely nothing more than a struct containing a single C array.

Sign up to request clarification or add additional context in comments.

6 Comments

I agree that this will work with every sensible implementation of the standard library, but there is nothing in the standard that guarantees it, right? Some implementation of std::array could perhaps add some additional debugging fields before the actual array...
I suspect it's Undefined Behavior. Yes, a std::array<T,N> contains a T[N]. That doesn't mean it is a T[N]. And accessing an object via an expresion of incompatible type is UB.
@michalsrb: No, std::array cannot contain additional debugging fields. Not only is there nothing sensible to debug by doing so, but the widespread use of std::array in a way that demands it is a simple array internally would never allow such an implementation to succeed (meaning, have users).
@JohnZwinck: I can imagine things you could debug on std::array. For example a debug version of standard library could add a canary field before and after the array contained in std::array and test them in every method to detect out-of-bounds writes. That is plausible thing to do. It wouldn't break valid programs, but will break programs with this reinterpret_cast.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.