Code: Select all
#include
#include
#include
#include
template
concept trivially_copyable = std::is_trivially_copyable_v;
namespace details {
// required to pass a plain array to and from bit_cast
template
struct wrap_array {
T arr[N];
};
} // namespace details
template
constexpr void set_byte(T& obj, std::size_t pos, std::byte val) {
details::wrap_array obj_rep;
// static only with c++>=23
// static details::wrap_array obj_rep;
obj_rep = std::bit_cast(obj);
if (pos >= sizeof(T)) {
return;
}
obj_rep.arr[pos] = val;
obj = std::bit_cast(obj_rep);
}
Ich frage mich, ob dieses Snippet für Strukturen mit Auffüllung wie dem in dieser Frage vorgeschlagenen definiert ist (die Frage wäre dieselbe für eine Struktur mit Bitfeldern):
Code: Select all
#include
struct S40 {
std::uint8_t a = 0x51;
std::uint32_t b = 0xa353c0f1;
};
Laut der neuesten Version von std::bit_cast:
Wenn u vom Typ „normaler Zeichentyp ohne Vorzeichen“ oder vom Typ „std::“byte ist, hat u einen unbestimmten Wert, wenn eines der Bits in seiner Wertdarstellung unbestimmt ist, oder hat andernfalls einen fehlerhaften Wert.
Der erste std::bit_cast oben erzeugt also einige std::bytes mit unbestimmten Werten.
Fällt es unter die Ausnahmen in basic.indet, wodurch das Programm in einem definierten Zustand bleibt und das Lesen dieses Werts ermöglicht wird, auch wenn er unbestimmt ist?
Gehe noch einen Schritt weiter, wenn ich ein Byte ändere, das einen unbestimmten Wert enthält (Geben Sie ihm jetzt ein bestimmtes) und führen Sie den zweiten std::bit_cast aus. https://eel.is/c++draft/bit.cast#4 gibt an, dass das Füllbit der zurückgegebenen Struktur „nicht spezifiziert“ ist, aber ich kann in diesem Kontext keine Definition dieses Konzepts finden (vielleicht nicht spezifiziertes Verhalten, das würde bedeuten, dass das Programm wohlgeformt ist, aber das genaue Ergebnis hängt von der tatsächlichen Implementierung ab).
Ist das Ergebnis Struktur gültig, während die Wertdarstellung einer gültigen für den Typ entspricht? Ohne undefiniertes Verhalten?
Mein Ziel ist es, sicherzustellen, dass die Funktion gültig ist, wenn ich nur Bytes ändern möchte, die an der Wertdarstellung beteiligt sind (die jedoch im Fall eines Bitfelds unbestimmte Bits enthalten können). Wenn ich versuche, Füllbytes/Bits zu ändern, erwarte ich, dass der Objektwert unverändert bleibt und sich das Programm gut verhält.
Mobile version