OFFSET -macro (also offsetof in ANSI-C)

ncpg ncpg at ehviea.ine.philips.nl
Tue Nov 27 03:19:20 AEST 1990


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



More information about the Comp.lang.c mailing list