Re: offsetof
- From: darkknight <gp.kiwi@xxxxxxxxx>
- Date: Fri, 30 Sep 2005 23:33:32 +1200
On 30 Sep 2005 02:17:50 -0700, luke wrote:
>hi all,
>i have another question.
>I've read the FAQ regarding my former question (sizeof struct and
>union) and in question 2.14 it talks about offset macro.
>
>#define offsetof(type, mem) ((size_t) \
> ((char *)&((type *)0)->mem - (char *)(type *)0))
>
>Can anyone explain me how it works.
>1)I can't understand what "0" casted to (type *) means
>2)Isn't the second menber of substraction "(char *)(type *)0" useless?
Well ... 0 casted to type * means this ...
The C language allows you to convert an integer to a pointer or a
pointer to an integer. The result of doing this is "implementation
defined" but as the C99 standard says
<quote>
The mapping functions for converting a pointer to an integer or an
integer to a pointer are intended to be consistent with the addressing
structure of the execution environment.
<end quote>
The idea being that you can convert the address of an object to an
integer and get sensible values e.g. if you have
char abc[16];
and abc is at physical address 0xFFFF0000 in memory, then
(int)&abc[0]
would most likely give you a value of 0xFFFF0000
and
(int)&abc[1] would give you 0xFFFF0001
One use for this is that if you need to read or write to a physical
location in memory you can do it like this
*(char*)0xFFFF0000 = 0x55;
On many machines, this would have the effect of setting abc[0] to 0x55.
Hence when you cast zero to (type *) you are converting an integer to a
pointer as if you have an object whose address is at physical location
0x00000000.
Then when you write &((type *)0)->mem you are taking the address of the
mem member of the fictitious object whose address is zero. When you
subtract the address of the start of the fictitious object ( (char
*)(type *)0) from the address of the mem member, you get its offset as
an integer (the exact type of the integer is ptrdiff_t)
The casts to char* are necessary so that the type of the two pointers
being subtracted are both char* giving the offset of the mem member in
units of char.
The expression (type*)0 does NOT create a NULL pointer constant unless
the type of "type" is void i.e. it is (void*)0.
darkknight
.
- References:
- offsetof
- From: luke
- offsetof
- Prev by Date: allocation alignment for global and local variables.
- Next by Date: Re: offsetof
- Previous by thread: Re: offsetof
- Next by thread: Re: offsetof
- Index(es):
Relevant Pages
|