The OFFSETOF() macro - GeeksforGeeks
The OFFSETOF() macro
- Difficulty Level : Hard
- Last Updated : 28 May, 2017
We know that the elements in a structure will be stored in sequential order of their declaration.
How to extract the displacement of an element in a structure? We can make use of offsetof macro.
Usually we call structure and union types (or classes with trivial constructors) as plain old data (POD) types, which will be used to aggregate other data types. The following non-standard macro can be used to get the displacement of an element in bytes from the base address of the structure variable.
#define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT))
Zero is casted to type of structure and required element’s address is accessed, which is casted to size_t. As per standard size_t is of type unsigned int. The overall expression results in the number of bytes after which the ELEMENT being placed in the structure.
For example, the following code returns 16 bytes (padding is considered on 32 bit machine) as displacement of the character variable c in the structure Pod.
#include <stdio.h>
#define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT))
typedef struct PodTag
{
int i;
double d;
char c;
} PodType;
int main()
{
printf("%d", OFFSETOF(PodType, c) );
getchar();
return 0;
}
In the above code, the following expression will return the displacement of element c in the structure PodType.
OFFSETOF(PodType, c);
After preprocessing stage the above macro expands to
((size_t)&(((PodType *)0)->c))
Since we are considering 0 as address of the structure variable, c will be placed after 16 bytes of its base address i.e. 0x00 + 0x10. Applying & on the structure element (in this case it is c) returns the address of the element which is 0x10. Casting the address to unsigned int (size_t) results in number of bytes the element is placed in the structure.
Note: We may consider the address operator & is redundant. Without address operator in macro, the code de-references the element of structure placed at NULL address. It causes an access violation exception (segmentation fault) at runtime.
Note that there are other ways to implement offsetof macro according to compiler behaviour. The ultimate goal is to extract displacement of the element.