Note that there are some explanatory texts on larger screens.

plurals
  1. POsizeof() part of a C struct - sort of
    primarykey
    data
    text
    <p>I want to grab part of the data inside some C structs to partially serialize/deserialize them, writing the bytes from memory to disk, and viceversa. </p> <p>The structs are not known in advance, they are dynamically built with my own C code generator (as well as the code that will serialize it). The serializable fields will be placed at the beginning of the struct.</p> <p>Let's say a have a struct with 4 fields, and the first two are to be serialized:</p> <pre><code>typedef struct { int8_t x1; int32_t x2; /* 1 + 4 = 5 bytes (if packed) */ int8_t y1; int32_t y2; /* 1 + 4 +1 + 4 = 10 bytes (if packed) */ } st; </code></pre> <p>I plan to grab the pointer to the struct variable and write/read the <code>n</code> bytes that cover those two first fields (<code>x1, x2</code>). I don't think I need to worry about alignment/packing because I don't intend the serialization to survive different compilations (only a unique executable is expected to read/write the data). And, as I'm targeting a wide scope of compilers-architectures, I don't want to place assumptions on alignment-packing or compiler specific tricks.</p> <p>Then, I need to count bytes. And I can't just do <code>sizeof(st.x1)+sizeof(st.x2)</code> because of alingment-padding. So, I'm planning to substract pointers, from the start of the struct to the first "non persistent" field:</p> <pre><code>st myst; int partsize = (char*)&amp;myst.y1 - (char*)(&amp;myst); printf("partial size=%d (total size=%d)\n",partsize,sizeof(myst)); </code></pre> <p>This seems to work. And it can be placed in a macro.</p> <p>(For the record: I tried also to write another macro that does not requrire an instance of the struct, something like <a href="https://stackoverflow.com/questions/3553296/c-sizeof-single-struct-member">this</a>, but it doesnt seem possible here - but this does not matter me much).</p> <p>My question: Is this correct and safe? Can you see any potential pitfall, or some better approach?</p> <p>Among other things: Does C standard (and de-facto compilers) assume that the structs fields lay in memory in the same order as they are defined in source? This probably is a stupid question, but I'd want to be sure...</p> <p>UPDATE: Some conclusions from the answers and my own findings:</p> <ol> <li><p>There seems to be no problem with my approach. In particular, C dictates that struct fields will never change order.</p></li> <li><p>One could also (as suggested by an aswer) count from the last persistent field and add its size : <code>(char*)&amp;myst.x2 + sizeof(&amp;myst.x2) - (char*)(&amp;myst)</code> . That would be equivalent, except that it would include not the padding bytes (if present) for the last field. A very small advantage - and a very small disadvantage, in being less simple.</p></li> <li><p>But the accepted answer, with <code>offsetof</code>, seems to be preferable than my proposal. It's clear-expressive and pure compile-time, it does not require an instance of the struct. It further seems to be standard, available in any compiler. If one does not need a compile-time construct, and has an instance of the struct available (as is my scenario) both solutions are esentially equivalent.</p></li> </ol>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload