basic problem
i'm in tricky situation requires taking pointer struct mainset
, turning pointer struct subset
, fields contiguous subset of fields of mainset
, starting first. such thing possible, well-defined behavior? realize pretty terrible thing do, have , frustrating reasons [explained @ bottom patient readers].
my attempt an implementation seems work, on os x clang compiler:
#include <iostream> struct mainset { size_t size; uint32_t reflex_size; }; struct subset { size_t size; }; using namespace std; int main(int argc, char *argv[]) { mainset test = {1, 1}; subset* stest = reinterpret_cast<subset*>(&test); std::cout << stest->size << std::endl; }
the output indeed 1, expect. however, wonder: getting lucky particular compiler , simple case (in reality structs more complicated), or work in general?
also, follow-up question: other annoying reasons, worry might need make larger struct
struct mainset { uint32_t reflex_size; size_t size; };
instead, field coming @ front. implementation extended work in case? tried replacing &test
&test+sizeof(test.reflex_size)
didn't work; output of cout
statement 0.
explanation of why have this
my project uses gsl library linear algebra. library makes use of structs of form
struct gsl_block { size_t size; double* data; }
and similar structs gsl_vector
, gsl_matrix
. so, i've used these structs members of c++ classes; no problem. demanded feature project, however, enable reflection classes reflex tool, part of root ecosystem. enable reflection struct in reflex, must add annotation like
struct gsl_block { size_t size; double* data; //[size] }
this annotation tells reflex that length of array provided field size
of same struct. that, but reflex , root have unfortunate limitation: length field must 32 bit. having been informed limitation won't fixed anytime soon, , not having time/resources fix myself, i'm looking workarounds. idea somehow embed struct bit-compatible gsl_block
within larger struct:
struct extended_gsl_block { size_t size; double* data; //[reflex_size] uint32_t reflex_size; }
and similar things gsl_vector
, gsl_matrix
; can ensure reflex_size
, size
equal (neither ever bigger ~50) , reflex able parse header correctly (i hope; if reflex_size required precede data field more difficult required). since gsl routines work pointers these structs, idea this: given pointer extended_gsl_block*
, somehow pointer fields size
, data
, reinterpret_cast
gsl_block*
.
you in luck.
the classes show example conform requirements of standard layout types.
you can read more here:
http://en.cppreference.com/w/cpp/language/data_members#standard_layout
you can test premise in compiler with:
static_assert(std::is_standard_layout<gsl_block>::value, "not standard layout");
Comments
Post a Comment