Search code examples
c++arraysc++11castingreinterpret-cast

What is the safest way to convert long integer into array of chars


Right now I have this code:

uint64_t buffer = 0;
const uint8_t * data = reinterpret_cast<uint8_t*>(&buffer);

And this works, but it seems risky due to the hanging pointer (and looks ugly too). I don't want naked pointers sitting around. I want to do something like this:

uint64_t buffer = 0;
const std::array<uint8_t, 8> data = partition_me_softly(buffer);

Is there and c++11 style construct that allows for me to get this into a safe container, preferable a std::array out of an unsigned int like this without inducing overhead?

If not, what would be the ideal way to improve this code to be more safe?


So I modified dauphic's answer to be a little more generic:

template <typename T, typename U>
std::array<T, sizeof(U) / sizeof(T)> ScalarToByteArray(const U v)
{
    static_assert(std::is_integral<T>::value && std::is_integral<U>::value, 
        "Template parameter must be a scalar type");
    std::array<T, sizeof(U) / sizeof(T)> ret;
    std::copy((T*)&v, ((T*)&v) + sizeof(U), ret.begin());
    return ret;
}

This way you can use it with more types like so:

uint64_t buffer = 0;
ScalarToByteArray<uint8_t>(buffer);

Solution

  • If you want to store an integer in a byte array, the best approach is probably to just cast the integer to a uint8_t* and copy it into an std::array. You're going to have to use raw pointers at some point, so your best option is to encapsulate the operation into a function.

    template<typename T>
    std::array<uint8_t, sizeof(T)> ScalarToByteArray(const T value)
    {
        static_assert(std::is_integral<T>::value, 
            "Template parameter must be a scalar type");
        std::array<uint8_t, sizeof(T)> result;
        std::copy((uint8_t*)&value, ((uint8_t*)&value) + sizeof(T), result.begin());
        return result;
    }