On Thursday 15 April 2010 13:56:00 Stephen Powell wrote:
> On Wed, 14 Apr 2010 23:10:55 -0400 (EDT), Boyd Stephen Smith Jr. wrote:
> > On Tuesday 13 April 2010 17:16:03 Stephen Powell wrote:
> >> What I need to do is to have two structures overlay each other; so that
> >> they occupy the same storage. To be specific, here is a structure
> >> which describes the volume label for an OS-formatted disk:
> >>
> >> struct __attribute__ ((packed)) volume_label {
> >> char volkey[4]; /* volume key = volume label */
> >> ...
> >> };
> >>
> >> And here is a structure which describes the volume label for a
> >> CMS-formatted disk:
> >>
> >> struct __attribute__ ((packed)) cms_label {
> >> char label_id[4]; /* Label identifier */
> >> ...
> >> };
> >
> > union any_label {
> > struct volume_label vl;
> > struct cms_label cl;
> > };
> >
> >> Note that both structures have as their first member a character
> >> variable of length 4. In the case of the "volume_label" structure it is
> >> "volkey" and in the case of the "cms_label" structure it is "label_id".
> >> If the value of this variable is "VOL1" (in EBCDIC) then it is the first
> >> structure which maps the storage. If the value of this variable is
> >> "CMS1" (in EBCDIC) then it is the second structure which maps the
> >> storage.
> >
> > union any_label *label = /* Initialize somehow */;
> > struct volume_label *maybe_vl = &label->vl;
> > struct cms_label *maybe_cl = &label->cl;
> >
> > if (strncmp(maybe_vl->volkey, "VOL1", 4) == 0) {
> > maybe_cl = NULL;
> > /* Use maybe_vl all you want, e.g. */
> > maybe_vl->security = 0xFF;
> > } else if (strncmp(maybe_cl->label_id, "CMS1", 4) == 0) {
> > maybe_vl = NULL;
> > /* Use maybe_cl all you want, e.g. */
> > printf("%lu\n", (unsigned long) maybe_cl->disk_offset);
> > } else {
> > assert(("Unrecognized disk!", 0));
> > }
>
> Thanks, Boyd. Your response comes the closest so far to what I'm looking
> for. Based on what I know from other programming languages, I don't think
> it's going to be necessary to explicitly declare a union.It's possible, but I would generally do it for clarity. I like using the types of variables/arguments as documentation, so I would store any data where the real type was unknown in the union. Then access it though a "struct cms_label *" or "struct volume_label *" one I had determined the correct type. Since C unions are not tagged, a C union is the same size as it's largest member. (NB: Not really sure how __attribute__((__packed__)) changes things, if at all; it's possible you need it on the union to prevent padding from being added after the space occupied by the largest member.) > In short, I need to (a) declare "cms_label" as a based structure, (above; timmmed) > (b) > declare a pointer variable called "cms_ptr" and associate it with the > "cms_label" structure, struct cms_label *cms_ptr; Initialization optional, but recommended. > (c) make sure that the compiler does not attempt > to allocate any storage for the "cms_label" structure, Since you are declaring a pointer to a structure, and not declaring an object with type "struct cms_label", no space will be allocated for a cms_label. > (d) make sure that > the compiler automatically acquires storage for the "cms_ptr" pointer > variable itself, Make your declaration a definition and that'll be handled. (Declarations and definitions look very similar for non-function types; the code given above is actually a definition if it is not within a struct/union type.) > (e) assign the address of the "volume_label" structure > to the "cms_ptr" pointer variable at an appropriate point in the code, > and struct volume_label vl; struct cms_label *cms_ptr; /* Load data into vl */ /* Determine that the data is actually a cms_label */ cms_ptr = (void *) &vl; Or, in your specific case, you should be able to do something like: struct cms_label *cms_ptr = (void *) disk_specific->anchor->vlabel; Since you are already dealing with a "struct volume_label *", there's no need for the address-of operator (&). > (f) make references to the members of the cms_label structure. cms_ptr->label_id; /* Or any other member. */ > How do I do this? (Man, I wish I knew C!) Examples above good? Please let me know if I can provide further assistance. -- Boyd Stephen Smith Jr. ,= ,-_-. =. [email protected] ((_/)o o(\_)) ICQ: 514984 YM/AIM: DaTwinkDaddy `-'(. .)`-' http://iguanasuicide.net/ \_/
signature.asc
Description: This is a digitally signed message part.

