playORM может сделать это для вас, используя S-SQL (масштабируемый SQL), который просто добавляет разделение, так что вы можете делать объединения внутри разделов.
pointer->res.a
в порядке, но поведение pointer->res.b
не определено.
Может быть произвольное количество отступов между a
и b
членами.
Некоторые компиляторы позволяют вам указать, что между членами нет заполнения, но, конечно, вы отказываетесь от переносимости.
C не налагает правила о том, сколько отступов осталось между 2 последовательными членами структуры.
Вот почему реализации определяют много директив #pragma - специально для изменения этого поведения.
Итак, как говорится в ответе Вирсавии, ...->b
не определено.
Я ответил на тот же вопрос некоторое время назад, здесь .
Наказание указателя небезопасно. Вместо этого используйте настоящий союзный удар.
Допущения: структура правильно упакована (нет заполнения между элементами)
#include <stdio.h>
#include <string.h>
struct __attribute__((packed)) result{
int a;
int b;
int c;
int d;
};
union convert{
int arr[4];
struct result res;
};
volatile int arr1[4];
void foo(void)
{
union convert cnv;
memcpy(&cnv, (void *)arr1, sizeof(arr1));
printf("%d %d\n", cnv.res.a, cnv.res.b);
}
все современные компиляторы оптимизируют вызов memcpy
https : //godbolt.org/z/4qtRIF
.LC0:
.string "%d %d\n"
foo:
mov rsi, QWORD PTR arr1[rip]
xor eax, eax
mov rdi, QWORD PTR arr1[rip+8]
mov edi, OFFSET FLAT:.LC0
mov rdx, rsi
sar rdx, 32
jmp printf