What is the cpp14 idiomatic way to read int32_t from a char * buffer?

Given the char c buffer containing int (little endian). How to read it as int32_t?

I wrote this code, but it does not feel idiomatic cpp.

int32_t v;
char* p = (char*)&v;
for (int i=0; i < 4; i++) {
    *(p+i) = *(c+i);
}
+6
source share
4 answers

If you want to solve the problem in a portable and safe way, use memcpyhow nm's answer is explained . Otherwise, there is a more dangerous technique:

Please note that this is UB. Use only that method if you are completely sure that the buffer contains the required amount of data and that the buffer and data are correctly aligned .

, , char*, reinterpret_cast:

std::int32_t v = *reinterpret_cast<std::int32_t*>(p);

. . .

+5

char* - memcpy ( - merhod, std::copy , ).

 memcpy(&my_number, my_buffer, sizeof(my_number));

, . tyoe , endianness . ( , ), (, htonl ).

+7

- endianness - -. htonl() ntohl() ( ), ( ). , ( ).

+6

There is no standard function to detect the validity of your syatem. However, given a function bool is_little_endian()that returns true only on small systems, you can do something like this:

std::uint32_t read_from_little_endian(char* buf)
{
    std::uint32_t u;

    if(is_little_endian())
        std::copy(buf, buf + sizeof(u), (char*)&u);
    else
        std::reverse_copy(buf, buf + sizeof(u), (char*)&u);

    return u;
}

The important point is always to bring std::uint32_t*to char*, because only char*can legally aliases of all the other types.

+3
source

All Articles