Offseting in Structures

S

Sekhar

While going through one discussion forum i come across one interesting
query.

Without creating an object how to find the offset of a structure member
variable.

Something like

struct A
{
double i;
int j;
}

OFFSETOF(A, j) should return offset of member variable j.

I come across one standard function in stddef.h where this is already
defined as

#define offsetof(s,m) (size_t)&(((s *)0)->m)

and is working fine and the above snippet is giving me 8 on a VC++ 6.0
compiler

Can anyone shed some light of how this is working.

Thanks and Regards
Sujil C
 
A

Alf P. Steinbach

* Sekhar:
While going through one discussion forum i come across one interesting
query.

Without creating an object how to find the offset of a structure member
variable.

Something like

struct A
{
double i;
int j;
}

OFFSETOF(A, j) should return offset of member variable j.

I come across one standard function in stddef.h where this is already
defined as

#define offsetof(s,m) (size_t)&(((s *)0)->m)

and is working fine and the above snippet is giving me 8 on a VC++ 6.0
compiler

Can anyone shed some light of how this is working.

It's compiler specific, relying on knowledge that with this compiler a
nullpointer corresponds to address 0, and that with this compiler it can
be dereferenced.

The standard library /implementation/ can use such compiler-specific
features, and this implementation does.

It won't necessarily work with other compilers.
 
J

Jim Langston

Alf P. Steinbach said:
* Sekhar:

It's compiler specific, relying on knowledge that with this compiler a
nullpointer corresponds to address 0, and that with this compiler it can
be dereferenced.

The standard library /implementation/ can use such compiler-specific
features, and this implementation does.

It won't necessarily work with other compilers.

I don't neccessarily see where it counts a null pointer. It seems the same
result would be concluded by:

A* ap = 0;
size_t offset = (size_t) &ap->m;
 
A

Alf P. Steinbach

* Jim Langston:
I don't neccessarily see where it counts a null pointer.
Huh?

It seems the same
result would be concluded by:

A* ap = 0;
size_t offset = (size_t) &ap->m;

Yes.

But note that if a nullpointer is actually address 0x0FFFFFFF, or
something, then this will/may produce something very much different than
the offset.

That's where the nullpointer representation enters the picture; the
ability to dereference a known nullpointer in this context is also
crucial, although that's something I think one can rely on with every
existing C++ compiler.
 
G

Gianni Mariani

Alf P. Steinbach wrote:
....
Yes.

But note that if a nullpointer is actually address 0x0FFFFFFF, or
something,...

Strictly speaking, you are correct. However I have never ever seen
null implemented as somthing other than 0 and I suspect I never will.
So practically speaking, it is irrelevant.
 
S

Stuart Redmann

Alf said:
* Sekhar:



It's compiler specific, relying on knowledge that with this compiler a
nullpointer corresponds to address 0, and that with this compiler it can
be dereferenced.

The standard library /implementation/ can use such compiler-specific
features, and this implementation does.

It won't necessarily work with other compilers.

Alf is supposedly a mathematician, because his answer is
(a) completely right, and
(b) utterly useless.

I think what you want to know is how the expression
"(size_t)&(((s *)0)->m)"
works, assuming that the null pointer representation of your compiler is
0x0. Let's interpret this expression one step at a time.

"(s *)0" denotes a pointer of type s that points to the memory location
0x0 (this is the compiler specific part, since it may point to any
location your compiler vendor can think of).

"((s *)0)->m" is the member m of the null pointer. Since the null
pointer points to the physical address 0x0, this expression effectively
is the offset of the member m of an object of class s.

"&(((s *)0)->m)" takes the address of the member m of the null pointer.
Note that the expression "((s *)0)->m" is not the address of the member
m but the _value_ of m. Nevertheless the expression "((s *)0)->m" is
also a lvalue, thus the address of the expression can be retrieved.

"(size_t)&(((s *)0)->m)" simply casts the address of member m of the
null pointer to the type size_t.

The expression is not platform independent, but can be made so quite
easily. I leave it as a interesting task for you to try.

Regards,
Stuart
 
S

Sekhar

Stuart said:
Alf is supposedly a mathematician, because his answer is
(a) completely right, and
(b) utterly useless.

I think what you want to know is how the expression
"(size_t)&(((s *)0)->m)"
works, assuming that the null pointer representation of your compiler is
0x0. Let's interpret this expression one step at a time.

"(s *)0" denotes a pointer of type s that points to the memory location
0x0 (this is the compiler specific part, since it may point to any
location your compiler vendor can think of).

"((s *)0)->m" is the member m of the null pointer. Since the null
pointer points to the physical address 0x0, this expression effectively
is the offset of the member m of an object of class s.

"&(((s *)0)->m)" takes the address of the member m of the null pointer.
Note that the expression "((s *)0)->m" is not the address of the member
m but the _value_ of m. Nevertheless the expression "((s *)0)->m" is
also a lvalue, thus the address of the expression can be retrieved.

"(size_t)&(((s *)0)->m)" simply casts the address of member m of the
null pointer to the type size_t.

The expression is not platform independent, but can be made so quite
easily. I leave it as a interesting task for you to try.

Regards,
Stuart


Thanks Stuart for giving me exactly what i want
 
B

BigBrian

Stuart said:
Alf is supposedly a mathematician, because his answer is
(a) completely right, and
(b) utterly useless.

IMHO, Alf's answer wasn't "utterly useless". This is a statement of
your opinion, not absolute fact.

-Brian
 
S

Stuart Redmann

BigBrian said:
Stuart Redmann wrote:




IMHO, Alf's answer wasn't "utterly useless". This is a statement of
your opinion, not absolute fact.

-Brian

Well, I thought people would spot that this comment was meant
sarcastically. As an ex-student of theoretical computer science I have
deep respect of all mathematicians (including my wife), so I hope Alf
won't hold a grudge against me. The original joke goes like this:

A man climbs a mountain and gets lost. By chance there is a balloon
flying by, so he shouts 'Do you know where you are?' After some time he
gets the reply 'In a balloon.' How do we know that the balloon driver is
a mathematician?
Well, there are three indicators:
(a) his answer is well thought about,
(b) his answer is completey right, and
(c) his answer is utterly useless.

Regards,
Stuart
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,431
Messages
2,571,678
Members
48,796
Latest member
Greg L.

Latest Threads

Top