memory offset of member variable within class

J

John Goche

Hello,

Consider the following macro to get the
memory offset of a class data member:

#define OFFSET(CLASSNAME, MEMBER) ((int) (&((CLASSNAME *) 0)->MEMBER))

Given that 0 may not be the address of
an instance of CLASSNAME, will this
code be legal in standard C++?

Thanks,

JG
 
V

Victor Bazarov

John said:
Consider the following macro to get the
memory offset of a class data member:

#define OFFSET(CLASSNAME, MEMBER) ((int) (&((CLASSNAME *) 0)->MEMBER))

Given that 0 may not be the address of
an instance of CLASSNAME, will this
code be legal in standard C++?

Nit: the code is just a definition. It's ignored unless you actually
use the macro. You didn't use the macro.

Now, if the macro is used, then yes, but only if a POD struct is the
first argument.

V
 
F

Frederick Gotham

John Goche:
Consider the following macro to get the
memory offset of a class data member:

#define OFFSET(CLASSNAME, MEMBER) ((int) (&((CLASSNAME *) 0)->MEMBER))

Given that 0 may not be the address of
an instance of CLASSNAME, will this
code be legal in standard C++?


The C++ Standard does not define the behaviour of the deferencing of a null
pointer.

In your example:

((T*)0)->field

is equal to:

(*(T*)0).field

As you can see, a null pointer is dereferenced.
 
G

Gianni Mariani

John said:
Hello,

Consider the following macro to get the
memory offset of a class data member:

#define OFFSET(CLASSNAME, MEMBER) ((int) (&((CLASSNAME *) 0)->MEMBER))

Given that 0 may not be the address of
an instance of CLASSNAME, will this
code be legal in standard C++?


This kind of "address of" operator is replaced with "address of member".
i.e.

struct A { int b; int c; };

int A::* x = & A::b;

x = & A::c;

See if your code can be changed to use this C++ construct.
 
K

Kavya

Frederick said:
The C++ Standard does not define the behaviour of the deferencing of a null
pointer.

In your example:

((T*)0)->field

is equal to:

(*(T*)0).field

As you can see, a null pointer is dereferenced.

Derefrencing a null pointer in not undefined behavior. Using the
resulting value is undefined behavior.
 
G

Gianni Mariani

Kavya said:
Derefrencing a null pointer in not undefined behavior. Using the
resulting value is undefined behavior.

Actually, it is undefined. Practically every compiler I know does not
do anything "unexpected", that's a different story. I do think that the
standard should allow it though. Member addresses (T S::*) IMHO is a
much better alternative.
 
F

Frederick Gotham

Just to clarify the misinformation posted in this thread.

(1) The behaviour produced as a result of dereferencing a null pointer is
not defined by the C++ Standard.
(2) The behaviour of pointer arithmetic upon a null pointer is not defined
by the C++ Standard.
(3) The nature of pointer arithmetic is entirely up to the implementor, and
the C++ Standard does not necessitate that it operate in the same fashion
as integer arithmetic.

Therefore, the behaviour of the following expression upon its evaluation is
undefined:

*(T*)0

Furthermore, the behaviour of the following expression upon its evaluation
is undefined:

(*(T*)0).field

As is:

((T*)0)->field

As is:

&((T*)0)->field

Even it the dereferencing of a null pointer did not invoke undefined
behaviour, the evaluation to false of the following expression would still
not be guaranteed.

(T*)0 + 1 - 1
 
J

Jack Klein

Derefrencing a null pointer in not undefined behavior. Using the
resulting value is undefined behavior.

Just plain old flat out wrong. Literally contradicted in so many
words by the C++ standard, no subtle interpretations needed.

Paragraph 4 of 1.9:

"Certain other operations are described in this International Standard
as undefined (for example, the effect of dereferencing the null
pointer). [Note: this International Standard imposes no requirements
on the behavior of programs that contain undefined behavior.]"

Has nothing at all to do with what you do or do not try to do with the
resulting value. In fact, there is no "resulting value". Since the
C++ standard also states (paragraph 1 of 4.10:

"A null pointer constant is an integral constant expression (5.19)
rvalue of integer type that evaluates to zero. A null pointer constant
can be converted to a pointer type; the result is the null pointer
value of that type and is distinguishable from every other value of
pointer to object or pointer to function type."

....a null pointer does not point to any object or function, there
since it points to nothing there is no value to be had.
 
K

Kavya

Jack said:
Derefrencing a null pointer in not undefined behavior. Using the
resulting value is undefined behavior.

Just plain old flat out wrong. Literally contradicted in so many
words by the C++ standard, no subtle interpretations needed.

Paragraph 4 of 1.9:

"Certain other operations are described in this International Standard
as undefined (for example, the effect of dereferencing the null
pointer). [Note: this International Standard imposes no requirements
on the behavior of programs that contain undefined behavior.]"

Has nothing at all to do with what you do or do not try to do with the
resulting value. In fact, there is no "resulting value". Since the
C++ standard also states (paragraph 1 of 4.10:

"A null pointer constant is an integral constant expression (5.19)
rvalue of integer type that evaluates to zero. A null pointer constant
can be converted to a pointer type; the result is the null pointer
value of that type and is distinguishable from every other value of
pointer to object or pointer to function type."

...a null pointer does not point to any object or function, there
since it points to nothing there is no value to be had.

Sir, can you please look at this
http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#232
 
S

Steve Pope

If I were an implementer, I would want my implementation to
be free to possibly seg-fault if address zero, or an address one past
and array, were dereferenced.

Unless you'all are using a different definition of "dereference"
than I am...

S.
 

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

Forum statistics

Threads
473,768
Messages
2,569,575
Members
45,053
Latest member
billing-software

Latest Threads

Top