mark@DRD.Com (Mark Lawrence) (09/26/89)
I'm implementing a shared data area which has a companion data dictionary (also in shared memory) to describe the contents of the shared data area. The shared data area is implemented as one big struct with lots of elements. The data dictionary is defined as an array of structs, each describing one of the elements in the shared data area. I use #define'd symbols as indices into the array of structs to find the description of an element in the shared data area. A part of the description is the address of the element of interest. The dictionary and the shared data area will reside in shared memory (System V style). I maintain a global pointer to the beginning of the shared data area and the shared dictionary area. Since the shared data area could potentially get mapped in at different virtual memory places among user processes, I had intended to store a relative offset from the beginning of the shared data area for an element into the dictionary structure for that element and simply add on the base address for the shared data area (from the user processes perspective) at time of access to yield the 'real' virtual memory address of the element of interest (gad, that was long). Of course, the converse is required at startup time to cook up the offsets in the first place, e.g. shdata * sdp; offset = &(sdp->ElementOfInterest) - sdp; /* then stuff the offset into the relevant element of the data dictionary */ Using gcc 1.35 on SunOS 4.0.3, I find that such attempts to + and - pointers and addresses yields compiler complaints about invalid operands to binary operators. I get this whether I cast the pointers to void * or char * or simply leave them typed as is. I understand why it probably doesn't make sense (in portable way) to simple 'add' and 'substact' pointers to come up with offsets and recalculate, but I'm sure there is an approved way. Can anybody give me pointers to an operator or 'standard' macro that achieve's what I desire? -- mark@DRD.Com (918) 743-3013 Jer. 9:23,24 {uunet,rutgers}!drd!mark
barmar@kulla (Barry Margolin) (09/27/89)
Since you're using GCC, and GCC claims to be pANS-conforming, it should have the "offsetof" operator. Given a structure and an element of the structure, this will return the offset of the element into the structure. I'm surprised, however, that GCC complains when you try offset = (char *)&(sdp->ElementOfInterest) - (char *)sdp; The operands to the - operator are both char*, and they both point into the same object, so it should be OK to subtract them. The pANS defines the meaning of subtraction of pointers within the same object, so the above should be portable. Barry Margolin, Thinking Machines Corp. barmar@think.com {uunet,harvard}!think!barmar
hunt@hobbit.DG.COM (Greg Hunt) (09/29/89)
Try this (it works for me under GCC):
#define MEMBER_OFFSET(mo_struct, mo_member) \
((int32_type) (char_type *) & (((mo_struct *) 0) -> mo_member))
The following operation is allowed with MEMBER_OFFSET:
typedef any_struct_type {
.....
<type> member_name_within_struct;
.....
} ANY_STRUCT_TYPE;
<int32_type> = MEMBER_OFFSET (ANY_STRUCT_TYPE,
member_name_within_struct);
Note that the "structure type" passed MUST be a typedef structure
name, not a typedef tag name, nor an instance of the structure. The
member name must be within the structure, and can be any type except
bit field.
I define int32_type as long int and char_type as char.
Hope it works for you.
------------------------------------------------------------------
Greg Hunt Internet: hunt@dg-rtp.dg.com
Data General Corporation UUCP: {world}!mcnc!rti!dg-rtp!hunt
RTP Software Development
RTP, NC. 27713