Note that there are some explanatory texts on larger screens.

plurals
  1. POgetting a substruct out of a big struct in C
    primarykey
    data
    text
    <p>I'm having a very big <code>struct</code> in an existing program. This struct includes a great number of bitfields.</p> <p>I wish to save a part of it (say, 10 fields out of 150).</p> <p>An example code I would use to save the subclass is:</p> <pre><code>typedef struct {int a;int b;char c} bigstruct; typedef struct {int a;char c;} smallstruct; void substruct(smallstruct *s,bigstruct *b) { s-&gt;a = b-&gt;a; s-&gt;c = b-&gt;c; } int save_struct(bigstruct *bs) { smallstruct s; substruct(&amp;s,bs); save_struct(s); } </code></pre> <p>I also wish that selecting which part of it wouldn't be too much hassle, since I wish to change it every now and then. The naive approach I presented before is very fragile and unmaintainable. When scaling up to 20 different fields, you have to change fields both in the <code>smallstruct</code>, and in the <code>substruct</code> function.</p> <p>I thought of two better approaches. Unfortunately both requires me to use some external <a href="http://hal.cs.berkeley.edu/cil/" rel="nofollow noreferrer">CIL</a> like tool to parse my structs.</p> <p>The first approach is automatically generating the <code>substruct</code> function. I'll just set the struct of <code>smallstruct</code>, and have a program that would parse it and generate the <code>substruct</code> function according to the fields in <code>smallstruct</code>.</p> <p>The second approach is building (with C parser) a meta-information about <code>bigstruct</code>, and then write a library that would allow me to access a specific field in the struct. It would be like ad-hoc implementation of Java's class reflection.</p> <p>For example, assuming no struct-alignment, for struct</p> <pre><code>struct st { int a; char c1:5; char c2:3; long d; } </code></pre> <p>I'll generate the following meta information:</p> <pre><code>int field2distance[] = {0,sizeof(int),sizeof(int),sizeof(int)+sizeof(char)} int field2size[] = {sizeof(int),1,1,sizeof(long)} int field2bitmask[] = {0,0x1F,0xE0,0}; char *fieldNames[] = {"a","c1","c2","d"}; </code></pre> <p>I'll get the <code>i</code><sup>th</sup> field with this function:</p> <pre><code>long getFieldData(void *strct,int i) { int distance = field2distance[i]; int size = field2size[i]; int bitmask = field2bitmask[i]; void *ptr = ((char *)strct + distance); long result; switch (size) { case 1: //char result = *(char*)ptr; break; case 2: //short result = *(short*)ptr; ... } if (bitmask == 0) return result; return (result &amp; bitmask) &gt;&gt; num_of_trailing_zeros(bitmask); } </code></pre> <p>Both methods requires extra work, but once the parser is in your makefile - changing the substruct is a breeze.</p> <p>However I'd rather do that without any external dependencies.</p> <p>Does anyone have any better idea? Where my ideas any good, is there some availible implementation of my ideas on the internet?</p>
    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.
    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