reflection does not work with __attribute__((packed));
Closed this issue · 2 comments
lbckmnn commented
Hey,
I am trying to reflect a packed struct but unfortunately that does not seem to work.
Minimal example:
#include <cista/reflection/for_each_field.h>
#include <cista/reflection/to_tuple.h>
#include <iostream>
struct Test {
int a;
int b;
int c;
} __attribute__((packed));
int main() {
Test test;
test.a = 3;
test.b = 4;
test.c = 5;
cista::for_each_field(test, [&](auto&& m) { std::cout << m << std::endl; });
}
The error is:
...
error: cannot bind packed field 'p1' to 'int&'
...
So the underlying issue seems to be that it is not possible to bind a member of a packed struct to a reference.
If i remove the attribute((packed)) it works just fine.
I guess there is not much we can do about it?
felixguendling commented
It seems like it's not possible to bind to a reference. However, using pointers seems to work:
#include "cista.h"
struct Test {
int a;
int b;
int c;
} __attribute__((packed));
template <typename T, typename Fn>
void for_each_field_ptr(T&& t, Fn&& fn) {
std::apply([&](auto&&... field_ptr) {
(fn(field_ptr), ...);
}, cista::to_ptr_tuple(t));
}
int main() {
for_each_field_ptr(Test{3, 4, 5}, [](auto* f) {
printf("%d\n", *f);
});
}
lbckmnn commented
thanks!
interestingly, using #pragma pack also seems to work:
#include "cista.h"
#include <iostream>
#pragma pack(push, 1)
struct Test {
int a;
int b;
short int c;
int d;
};
#pragma pack(pop)
int main() {
Test test;
test.a = 3;
test.b = 4;
test.c = 5;
test.d = 17;
cista::for_each_field(test, [&](auto&& m) { std::cout << +m << std::endl; });
}