weird #define statement

N

NKOBAYE027

can anyone tell me what this thing is supposed to do?

its from the stddef.h file for MSVC 6.0

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



I understand it up to the & after that I have *no* idea what is going
on...is s a variable or a type? what does the cast (s *) mean? is it a cast?
and what about this 0 thing? how do we know it has an m to point at? (Oo)

i'm clearly confused...

any clarifications would be welcome

regards,

L.
 
J

Jack Klein

can anyone tell me what this thing is supposed to do?

its from the stddef.h file for MSVC 6.0

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



I understand it up to the & after that I have *no* idea what is going
on...is s a variable or a type? what does the cast (s *) mean? is it a cast?
and what about this 0 thing? how do we know it has an m to point at? (Oo)

i'm clearly confused...

any clarifications would be welcome

regards,

L.

It is the ANSI/ISO standard macro offsetof() macro that has been part
of both the C and C++ language standards since the first 1989 ANSI C
standard.

It's purpose is to return a size_t value representing the offset, in
bytes, of a structure or union member from the beginning of the
enclosing type.

It is up to the compiler vendor to provide an implementation that
works with their compiler in <stdlib.h> or <cstdlib>, even though the
macro as written might technically have undefined behavior, which this
one does as it dereferences a null pointer. Note that an
implementation is allowed to do things that are not technically legal
in conforming user code.

Finally, the offsetof() macro has very severe limitations in C++. It
is basically valid only for POD type (pretty much C compatible)
structs, classes, and unions.
 
A

Alf P. Steinbach

* "NKOBAYE027 said:
can anyone tell me what this thing [offsetof macro] is supposed to do?

The offsetof macro returns the offset of member m in any struct S, like


// Conceptual only.
//
// Will probably work with any C++ compiler but is formally undefined
// due to reinterpret_cast (which would also be used by C-style cast).

S anObject;
char* pObject = reinterpret_cast<char*>( &anObject );
char* pMember = reinterpret_cast<char*>( &anObject.m );

assert( offsetof( S, m ) == pMember - pObject );


It's a standard macro.

But the implementation, and the assumptions built into the implementation,
is up to the compiler vendor.


its from the stddef.h file for MSVC 6.0

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



I understand it up to the & after that I have *no* idea what is going
on...is s a variable or a type? what does the cast (s *) mean? is it a cast?
Yes.


and what about this 0 thing? how do we know it has an m to point at? (Oo)

It hasn't.

If you do that yourself then you have Undefined Behavior, but the compiler
vendor's programmers presumably knows whether it's safe with this compiler.


i'm clearly confused...

Look in your documentation of 'offsetof'.

Don't care about how it's implemented.

But just to be complete: for this compiler it's implemented as a conversion to
size_t of (a pointer to (member m in (a struct s located at address 0))). This
is not guaranteed to work with other compilers. As mentioned, formally it's UB.
 
D

David White

NKOBAYE027 said:
can anyone tell me what this thing is supposed to do?

its from the stddef.h file for MSVC 6.0

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



I understand it up to the & after that I have *no* idea what is going
on...is s a variable or a type?

's' is a struct or class type.
what does the cast (s *) mean? is it a cast?
Yes.

and what about this 0 thing? how do we know it has an m to point at? (Oo)

Because 'm' is one of the macro's parameters. The caller has to ensure that
this parameter is a member of 's'.
i'm clearly confused...

any clarifications would be welcome

(s *)0
This converts address zero into a pointer to type 's'.

((s *)0)->m
This selects member 'm' of an 's' that is at adress zero.

&(((s *)0)->m)
This takes the address of that member. Since the 's' begins at zero, this
resolves to the numberof bytes the member 'm' is from the beginning of 's'.
In other words, it is the offset of member 'm' within 's'.

(size_t)&(((s *)0)->m)
This converts the offset in address form into the standard integral size
type, which you would want an offset to be.

It would take me too long to find out how many language rules this construct
would break if you wrote it yourself - a number of them I suspect. But it's
their own compiler, so they know how a given non-standard construct will
work.

DW
 
J

John Harrison

It would take me too long to find out how many language rules this construct
would break if you wrote it yourself - a number of them I suspect. But it's
their own compiler, so they know how a given non-standard construct will
work.

Incidentally, has anyone seen the offsetof macro defined in any other way?
It's hard to imagine any other technique that would work.

john
 
A

Alf P. Steinbach

* "John Harrison said:
Incidentally, has anyone seen the offsetof macro defined in any other way?

Don't know.

It's hard to imagine any other technique that would work.

It's extremely easy to imagine other techniques, e.g.


#define offsetof( s, m ) __offsetof( s, m )


where __offsetof( s, m ) is a compiler intrinsic.
 
J

John Harrison

It's extremely easy to imagine other techniques, e.g.


#define offsetof( s, m ) __offsetof( s, m )


where __offsetof( s, m ) is a compiler intrinsic.

Well, that isn't exactly what I meant.

john
 
N

NKOBAYE027

Thanks for all the great help and my apologies for the cross-post with
comp.programming - was a snafu on my part.

regards,
L.
 
D

David White

John Harrison said:
Incidentally, has anyone seen the offsetof macro defined in any other way?
It's hard to imagine any other technique that would work.

I think it's a bit nasty that it turns an address directly into an integral
type. The difference between two addresses would be more appealing, though
more verbose.

DW
 

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
473,755
Messages
2,569,536
Members
45,013
Latest member
KatriceSwa

Latest Threads

Top