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. The >> volume_label structure is apparently a based structure, as references to >> the volkey variable look something like this: > > 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)); > } > > Hope that helps.
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. They will overlap each other implicitly because their pointers are the same. Both structure mappings occupy exactly 80 bytes of storage. And the storage for one of them is already allocated somehow. What I need to do is associate a pointer with the new structure and assign a value to the pointer that matches the pointer for the other structure. That will implicitly cause the two structures to overlap in storage. Here are examples from two other languages that I do know: s390 assembler language and PL/I. Here is the assembler example: ---------- ... CLC LABELIDA,=C'VOL1' Is this structure type A? BE VOL1CODE Yes - branch to label VOL1CODE LA 3,STRUCTA No - load the address of STRUCTA into register 3 USING STRUCTB,3 Tell the assembler that the address of STRUCTB is in register 3 L 4,FIELDB2 Load the fullword at FIELDB2 into register 4 ... Perform additional processing DROP 3 Tell the assembler that it can no longer assume that register 3 points to STRUCTB B COMCODE Rejoin common code VOL1CODE DS 0H ... Proceed with processing for structure type A COMCODE DS 0H ... STRUCTA DS 0CL12 LABELIDA DS CL4 FIELDA1 DS CL8 ... STRUCTB DSECT , Start a dummy control section (based structure) LABELIDB DS CL4 FIELDB1 DS F FIELDB2 DS F ... ---------- Here is the PL/I example: ---------- DCL 1 STRUCTA, 2 LABELIDA CHAR (4), 2 FIELDA1 CHAR (8); DCL ADDR BUILTIN; DCL B_PTR POINTER; DCL 1 STRUCTB BASED (B_PTR), 2 LABELIDB CHAR (4), 2 FIELDB1 FIXED BINARY (31,0), 2 FIELDB2 FIXED BINARY (31,0); ... IF LABELIDA = 'VOL1' THEN DO; /* Processing that refers to elements of STRUCTA */ END; ELSE DO; B_PTR = ADDR(STRUCTA); /* Processing that refers to elements of STRUCTB */ END; ---------- Now back to C. At the point in the code where I need to make a reference to the "disk_offset" member of the "cms_label" structure, I know that I can validly reference the "volkey" variable of the "volume_label" structure like this: disk_specific->anchor->vlabel->volkey What I need to do is declare that "cms_label" is a based structure and associate a pointer variable, say "cms_ptr", with it. But I don't want any storage to be allocated for the structure: only for the pointer. Storage should be allocated for the pointer, but it should not be initialized to anything. Then I can assign a value to the pointer, with something like: cms_ptr = disk_specific->anchor->vlabel; Then I can make references to members of the cms_label structure implicitly using the cms_ptr pointer variable. No storage is ever allocated to the "cms_label" structure. It overlays the "volume_label" structure implicitly via the assignment of a value to its associated pointer variable. I know how to do something like this in s390 assembler language and PL/I. Surely there must be a way to do this in C, right? In short, I need to (a) declare "cms_label" as a based structure, (b) declare a pointer variable called "cms_ptr" and associate it with the "cms_label" structure, (c) make sure that the compiler does not attempt to allocate any storage for the "cms_label" structure, (d) make sure that the compiler automatically acquires storage for the "cms_ptr" pointer variable itself, (e) assign the address of the "volume_label" structure to the "cms_ptr" pointer variable at an appropriate point in the code, and (f) make references to the members of the cms_label structure. How do I do this? (Man, I wish I knew C!) -- .''`. Stephen Powell : :' : `. `'` `- -- To UNSUBSCRIBE, email to debian-user-requ...@lists.debian.org with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org Archive: http://lists.debian.org/749326468.47646.1271357760265.javamail.r...@md01.wow.synacor.com