Offset of a data member

mr.anandc's Avatar, Join Date: May 2008
Go4Expert Member
Hi,

The below macro is defined in stddef.h standard header file.
#define offsetof(s,m) (size_t)&(((s *)0)->m)

This gives offset of member data 'm' in structure 's'

Ex:
struct example {
int a;
int b;
};

printf("%d", offsetof(example, b) ) displays 4 (In win32).

Can any one explain how offsetof macro is working?

Thanks.
asadullah.ansari's Avatar, Join Date: Jan 2008
TechCake
(size_t)&(((s *)0)->m)


(s*)(0) = 0 is integer which is cast to s pointer
((s*)(0))->m = Data member access
&(((s*)(0))->m) = Address of data member m
(size_t)&(((s*)(0))->m) = cast to standard integer(unsigned)
asadullah.ansari's Avatar, Join Date: Jan 2008
TechCake
You can see this also...
struct Data *ptr = 0;

printf("%d\n",&(ptr->b));
mr.anandc's Avatar, Join Date: May 2008
Go4Expert Member
Here my doubt is, if ptr value is 0 which is NULL, why access to b using ptr (ptr->b) is not crashing .

Thanks.
asadullah.ansari's Avatar, Join Date: Jan 2008
TechCake
Quote:
Originally Posted by mr.anandc
Here my doubt is, if ptr value is 0 which is NULL, why access to b using ptr (ptr->b) is not crashing .

Thanks.

That is Now your Intelligent question!!!
Code:
#include<stdio.h>
#include<stdlib.h>
#define offsetof(s,m) (size_t)&(((s *)0)->m)
#define Off(i,j)  ((i*)0)->j


struct Data
{
 int a;
 int b;
};

int main()
{
  int OffSet=offsetof(Data, b);
  printf("%d", OffSet) ;
  return 0;
}

In above  code , You are only getting the address not accessing.


int main()
{ 
  int Add=Off(Data , b);
  printf("%d", Add) ;
  return 0;
}
In this code , now you are accessing so segmentation fault will come.

Last edited by shabbir; 9May2008 at 11:29.. Reason: Code block
mr.anandc's Avatar, Join Date: May 2008
Go4Expert Member
Not yet cleared.
Here how it is able differentiate between accessing address and accessing a member.
Suppose in below statement
#define offsetof(s,m) (size_t)&(((s *)0)->m)

It is accessing address only. But before address operator, it is accessing member using ((s *)0)->m. How this is different from ((i*)0)->j.
asadullah.ansari's Avatar, Join Date: Jan 2008
TechCake
There is no difference b/w ((s *)0)->m and ((i*)0)->j .

But when you write statement (size_t)&(((s *)0)->m)
Then It will not go for accessing the member data. It's not like intermediate step ((s *)0)->m.
just address .

If you have doubt then tell me?
mr.anandc's Avatar, Join Date: May 2008
Go4Expert Member
Then how compiler will differentiate between the two statements, so that it accesses only address of a member.
asadullah.ansari's Avatar, Join Date: Jan 2008
TechCake
there is differencce b/w &i and i.

&i means not accessing i only address of i. compiler knows &i and i difference