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 Rooij
gwyn@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.