如何使用指针合法访问对齐错误的对象?
How can I legally access object with wrong alignment using pointer?
我需要 read/write 对象使用指向错误对齐位置的指针。我不想
使用 pragma pack
或其他特定于编译器的功能。
起初,我试过这个:
char arr[sizeof (float) * 2];
*(float *)(arr + 1) = 1.0;
但此代码会导致 UB,因为它违反了严格的别名规则。
如果没有 pragma pack
,下一个代码也将无法运行,因为编译器可能会在 : 8;
.
之后插入一个填充
union
{
struct
{
char arr[sizeof (float) * 2]
} a;
struct
{
: 8;
float val;
} b;
} data;
data.b.val = 1.0;
那么,我可以合法地访问指向错误对齐位置的指针的对象吗?
我可以将对象逐字节复制到需要的位置(或 memcpy),但我认为它会很慢,所以我正在尝试寻找其他解决方案。
更新:是的,我知道 alignas
,但它只能增加对齐,而不是减少它。
您始终可以在 C 中将对象作为 unsigned char
的数组访问( 而不是 相反)。
由于 char
的大小和对齐方式为 1,因此您可以随心所欲地访问内容。
请注意,尽管在 C++ 中事情并不是那么好:
除非类型可平凡复制,否则字节复制是不允许的。
我需要 read/write 对象使用指向错误对齐位置的指针。我不想
使用 pragma pack
或其他特定于编译器的功能。
起初,我试过这个:
char arr[sizeof (float) * 2];
*(float *)(arr + 1) = 1.0;
但此代码会导致 UB,因为它违反了严格的别名规则。
如果没有 pragma pack
,下一个代码也将无法运行,因为编译器可能会在 : 8;
.
union
{
struct
{
char arr[sizeof (float) * 2]
} a;
struct
{
: 8;
float val;
} b;
} data;
data.b.val = 1.0;
那么,我可以合法地访问指向错误对齐位置的指针的对象吗?
我可以将对象逐字节复制到需要的位置(或 memcpy),但我认为它会很慢,所以我正在尝试寻找其他解决方案。
更新:是的,我知道
alignas
,但它只能增加对齐,而不是减少它。
您始终可以在 C 中将对象作为 unsigned char
的数组访问( 而不是 相反)。
由于 char
的大小和对齐方式为 1,因此您可以随心所欲地访问内容。
请注意,尽管在 C++ 中事情并不是那么好:
除非类型可平凡复制,否则字节复制是不允许的。