c++ - Casting a pointer to a struct into another struct type with a smaller number of fields -


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