astrophobia
astrophobia

Reputation: 889

is it valid to copy a float array to an array of uint8_t using memcpy

I have an array of floats (4 bytes per float) and I want to copy the data to an array of bytes (uint8_t) and treat it as bytes. Later I may want to copy the byte data back to a float array and treat it again as floats for various operations. Is this valid in c++? In other words is something like this where I treat the floats temporarily as bytes valid?

std::array<std::uint8_t, 40> b;
b.fill(0);
std::array<float,10> f;
f.fill(3.14);
std::memcpy(b.data(),f.data(),40);
std::array<float,10> f2;
f2.fill(0);
std::memcpy(f2.data(),b.data(),40);
for(std::size_t i=0;i<10;i++)
{
  std::cout<<f2[i]<<std::endl; //now i want to access the float data
} 

Upvotes: 2

Views: 626

Answers (1)

Yeah, it's mostly fine1. I'm assuming uint8_t aliases a character type (which it does on modern platforms). Floats are trivially copyable, so moving them about like that is explicitly allowed:

[basic.types]

2 For any object (other than a base-class subobject) of trivially copyable type T, whether or not the object holds a valid value of type T, the underlying bytes ([intro.memory]) making up the object can be copied into an array of char, unsigned char, or std​::​byte ([cstddef.syn]). If the content of that array is copied back into the object, the object shall subsequently hold its original value.

The standard mandates you get back your floats if everything checks out. To be on the extra safe side one can add this check...

static_assert(std::is_same_v<unsigned char, std::uint8_t>);

... if you have too much code to alter. Otherwise, using std::byte is preferable to express you are dealing with raw bytes.


1 - See When is uint8_t ≠ unsigned char?, courtesy of @Ted Lyngmo.

Upvotes: 7

Related Questions