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.
In the above code, the following expression will return the displacement of element c in the structure PodType.
After preprocessing stage the above macro expands to
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. We will see practical usage of offsetof macro in liked lists to connect similar objects (for example thread pool) in another article.
Article compiled by Venki. Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.
- What’s difference between header files "stdio.h" and "stdlib.h" ?
- How to print a variable name in C?
- A C Programming Language Puzzle
- Arrays in C/C++
- Diffference between #define and const in C?
- Interesting Facts about Macros and Preprocessors in C
- Branch prediction macros in GCC
- Variable length arguments for Macros
- Multiline macros in C
- Memory Layout of C Programs
- CRASH() macro - interpretation
- Structure Member Alignment, Padding and Data Packing
- Increment (Decrement) operators require L-value Expression
- Write a C macro PRINT(x) which prints x
- Implement Your Own sizeof