ncpg@ehviea.ine.philips.nl (ncpg) (11/27/90)
I have a problem with "C" and its portability.
Our department is developing software in microsoft C 5.1.
When the software is tested, it is compiled with the Intel
protected mode compiler (ic286).
The problem can be described as follow:
I want to know the offset of a field within a structure.
This offset is used as an argument to a data base function, which
will use it to determine the key within the structure to select
an element.
struct x{
int a;
char b;
short key;
.
.
} X;
X *t;
short key;
t = DataBaseGet(DataBase, &key, sizeof(key), OFFSET(X, key));
In Microsoft 5.1, I declared the following macro:
I:
#define OFFSET(struct, field) ((unsigned short)(&(((struct*)0)->field)))
This (Nice) macro is standard on Microsoft 6.0 and it works.
The Intel Compiler gives warnings, so I tried something else:
II:
#define OFFSET(structPtr, field) ((unsigned short) \
(&((char *)(structPtr->field))) - \
&((char *)(structPtr)))
t = DataBaseSeek(DataBase, &key, sizeof(key), OFFSET(t, key));
This offset will compile on both machines, but at run time in
protected mode (intel C), t is pointer to a structure X and is not initialized.
OFFSET is now referring to an invalid address so I get a run-time error.
When I want to use II, I need to declare a variable (of type structure)
which is used only for this purpose. This is not acceptable.
Another possibility is is to hide this variable:
III:
#define OFFSET(struct, field, result) \
{ \
struct tmp; \
result = (int)((char *)&tmp.field - (char *)&tmp); \
}
The disadvantage of this methode is that it cannot be used as an argument
in a function call, so a temporary variable is needed, to store the result.
Is there anybody out there, that can help me.
Thanks in advance....
Tony de Goede & Guido van Rooijgwyn@smoke.brl.mil (Doug Gwyn) (11/28/90)
In article <898@ehviea.ine.philips.nl> ncpg@ehviea.ine.philips.nl (ncpg) writes: >#define OFFSET(structPtr, field) ((unsigned short) \ > (&((char *)(structPtr->field))) - \ > &((char *)(structPtr))) This wouldn't be right anyway. It's &structPtr->field that you want to use; you cannot apply & to the result of an object cast because it's not an lvalue.