Quantcast
Channel: std::bit_cast padding and undefined behavior - Stack Overflow
Viewing all articles
Browse latest Browse all 2

std::bit_cast padding and undefined behavior

$
0
0

I want to know how to use std::bit_cast in a well-defined way, noticeably in presence of indetermined bits. When is std::bit_cast usage defined behavior, when is it undefined behavior?

Thus I need a clarification about the wording of cppreference about std::bit_cast.I don't understand the meaning of the following paragraph:

For each bit in the value representation of the result that is indeterminate, the smallest object containing that bit has an indeterminate value; the behavior is undefined unless that object is of unsigned char or std::byte type. The result does not otherwise contain any indeterminate values.

When the input (From) is containing indeterminate bits (noticeably padding bits) what are the mentioned objects and what is meaning the distinction about their type (std::byte vs other)?

Let's write an example (not an actual use-case, merely an illustration of a situation with indeterminate bits):

#include <bit>#include <cstdint>struct S40 {    std::uint8_t a = 0x51;    std::uint32_t b = 0xa353c0f1;};struct S3 {    std::uint8_t a : 3;};int main() {    S40 s40;    std::uint64_t a64 = std::bit_cast<std::uint64_t>(s40);    // (3) on tested compilers, a64 is 0xa353c0f1UUUUUU51 where U is undefined byte    S3 s3;    s3.a = 0b101;    std::uint8_t a8 = std::bit_cast<std::uint8_t>(s3);    // (4) on tested compilers, a8 is uuuuu101, u being indeterminate bits}

Live
In this example, I'm playing with alignment in order to induce padding bits between a and b.
(note how clang is actually throwing garbage into the padding bits).
Is the production of a64 undefined behavior?
with S3, I tried to emulate a less than 1 byte type with padding bits.
Is the production of a8 defined behavior, while its value is undefined due to the presence of indeterminate bits?


For the record, I leave here the original example that tried to stress the possible difference between the 1 byte case and the other situations. But as it was rightly stressed in one answer, it does not demonstrate anything as passing a bit field inside the std::bit_cast implied an cast to a fully defined value (of its underlying type).

#include <bit>#include <cstdint>struct S9 {    std::uint16_t a : 9;};struct S7 {    std::uint8_t a : 7;};int main() {    S9 s9;    s9.a = 42;    std::uint16_t a16 = std::bit_cast<std::uint16_t>(s9.a);    // (1) a16 may be uuuuuuu000101010, u being indeterminate bits    S7 s7;    s7.a = 42;    std::uint8_t a8 = std::bit_cast<std::uint8_t>(s7.a);    // (2) a8 may be u0101010, u being indeterminate bits}

What are the objects we are speaking of?
Is the production of a8 considered as defined behavior, while its value is undefined?
Is the production of a16 considered as undefined behavior, while its value is undefined?



Viewing all articles
Browse latest Browse all 2

Latest Images

Trending Articles





Latest Images