Open In App

The OFFSETOF() macro

Improve
Improve
Improve
Like Article
Like
Save Article
Save
Share
Report issue
Report

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. 

C++




#include <iostream>
using namespace std;
 
#define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT))
 
typedef struct PodTag
{
   int i;
   double d;
   char c;
} PodType;
 
int main()
{
   cout << OFFSETOF(PodType, c);
 
   return 0;
}
 
// This code is contributed by sarajadhav12052009


C




#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("%lu", 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 

c




((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. 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.  References: 1. Linux Kernel code. 2. http://msdn.microsoft.com/en-us/library/dz4y9b9a.aspx 3. GNU C/C++ Compiler Documentation



Last Updated : 21 Jun, 2022
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads