Std::bit_cast заполнение и неопределенное поведениеC++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Std::bit_cast заполнение и неопределенное поведение

Сообщение Anonymous »

Я хочу знать, как использовать std::bit_cast четко определенным образом, особенно при наличии неопределенных битов. Когда поведение std::bit_cast определяется использованием, а когда поведение неопределенно?
Поэтому мне нужно уточнить формулировку cppreference о std::bit_cast.
Я не понимаю смысла следующего абзаца:

Для каждого бита в представлении значения результата, который является неопределенным, наименьший объект, содержащий этот бит, имеет неопределенный ценность; поведение не определено, если этот объект не имеет типа unsigned char или std::byte. В противном случае результат не содержит каких-либо неопределенных значений.

Когда входные данные () содержит неопределенные биты (заметно дополняющие биты), что представляют собой упомянутые объекты и что означает различие в их типе (

Код: Выделить всё

std::byte
против других)?
Давайте напишем пример (не реальный вариант использования, а просто иллюстрацию ситуации с неопределенными битами):

Код: Выделить всё

#include 
#include 
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(s40);
// (3) on tested compilers, a64 is 0xa353c0f1XXXXXX51 where X is indeterminate half-byte
S3 s3;
s3.a = 0b101;
std::uint8_t a8 = std::bit_cast(s3);
// (4) on tested compilers, a8 is xxxxx101, x being indeterminate bits
}
Live

В этом примере я играю с выравниванием, чтобы вызвать биты заполнения между a и b.

(обратите внимание, что clang на самом деле выбрасывает мусор в биты заполнения).

Является ли создание a64 неопределенным поведением?

с помощью S3 я попытался эмулировать less чем 1-байтовый тип с битами заполнения.

Является ли создание a8 определенным поведением, в то время как его значение неопределенно из-за присутствия неопределенных битов?

Для записи я оставляю здесь исходный пример, который пытался подчеркнуть возможную разницу между случаем с 1 байтом и другими ситуациями. Но, как было справедливо подчеркнуто в одном ответе, он ничего не демонстрирует, поскольку передача битового поля внутри std::bit_cast подразумевает приведение к полностью определенному значению (его базового типа).

Код: Выделить всё

#include 
#include 

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(s9.a);
// (1) a16 may be xxxxxxx000101010, x being indeterminate bits
S7 s7;
s7.a = 42;
std::uint8_t a8 = std::bit_cast(s7.a);
// (2) a8 may be x0101010, x being indeterminate bits
}
О каких объектах мы говорим?

Считается ли создание a8 определенным поведением, в то время как его значение неопределенно?

Считается ли создание a16 неопределенным поведением, в то время как его значение неопределенно?


Подробнее здесь: https://stackoverflow.com/questions/779 ... d-behavior
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»