Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I cast a std::array to slice? Or is there anything else I can use instead?

Is this undefined behavior?

std::array<int, 5> x = {3, 5, 1, 2, 3};
std::array<int, 3>& y = *reinterpret_cast<std::array<int, 3>*>(&x[1]);
for(int i = 0; i != 3; i++) {
    std::cout << y[i] << "\n";
}

Maybe yes, but I really feel like there should be a safe way to slice std::arrays.

EDIT: Following Radek's suggestion:

template<unsigned N, unsigned start, unsigned end, typename T>
std::array<T, end - start>& array_slice(std::array<T, N>& x)
{
    static_assert(start <= end, "start <= end");
    static_assert(end <= N-1, "end <= N");
    return *reinterpret_cast<std::array<T, end - start>*>(&x[start]);
}

EDIT: Ok, I decided that I'm unhappy with std::arrays and will move to something else, any ideas?

like image 912
Giovanni Funchal Avatar asked May 25 '12 20:05

Giovanni Funchal


1 Answers

Yes, that is undefined behavior. You're taking one type and reinterpret_casting it to another. Indeed, the use of the reinterpret_cast should be a big red flag for "here there be dragons!"

As for slicing arrays, that's not going to happen. A std::array contains values; a slice of this would contain references to part of that array. And therefore, it would not be a std::array. You can copy slices of arrays, but not using std::array. You would need to use std::vector, since it allows the calling of constructors, as well as construction from a range of values. Remember: std::array is just a nicer wrapper around a C-style array.

The committee is looking into a template array_ref<T> class, which is exactly what it says: a reference to some segment of an array of type T. This could be a regular C-style array, a std::vector, a std::array, or just some memory allocated with new T[]. There are some library implementations of the class already, but nothing is standardized yet.


Following Radek's suggestion:

Hiding the undefined behavior in a function does not make it defined behavior. You can try to pretend that it isn't undefined, but it still is. The moment you use that reinterpret_cast, you willingly give up living in C++-land.

like image 59
Nicol Bolas Avatar answered Sep 29 '22 07:09

Nicol Bolas