The behavior of your program is undefined. To explain why, it's easier
if I introduce two new objects:

point array[8];
point *pp = array;

Also, I will assume, in order to make my explanation more concrete, that
we're using an implementation where sizeof(int)==2, and puts no padding
in struct dummy. Then sizeof(point) == 6, offsetof(point,y)==2, and
offsetof(point, z)==4.

When you add an integer N to a pointer, it shifts that pointer by a
large enough amount memory to store N copies of the thing it points at.
Therfore, while pp currently points at array[0], pp+offsetof(point,y)
points at p[2]. pp+offsetof(point,z) points at array[4]. If converted to
(int*), those pointers would point at the 'x' members of those structures.

For the purposes of this rule, a single object is treated as an array of
length 1. Therefore, &a+offsetof(point,y) would, in principle, point at
a memory location that hasn't necessarily been reserved for use by your
program. That's why the behavior of your program is undefined.

To get the results you desire, you need to use:

int *p = (int*)((char*)&a + offsetof(point, y));

Since the sizeof(char)==1, adding N to a char* pointer moves it forward
by N bytes, which is what you are trying to do.
> i ran this program on DevC++ 4.9.9.2 and i'm getting some garbage
> values as output!

That's one of the plausible results from attempting to read memory that
you're not supposed to be reading.
--
James Kuyper

&a is the address of a and is of type point*. If sizeof (int) == 4,
offsetof(point, y) is probably 4. Adding 4 to a point* advances the
pointer by 4 point objects, *not* by 4 bytes.
> int *q = (int *)(&a + offsetof(point, z);

Likewise.
> printf("%d %d",*p,*q);

You should print a newline ("\n") at the end of the line of output.
> }
>
> ----------------------------------------------------------
> ---------------------------------------
>
> my question is will *p and *q really point to (a.x) and (a.y) ?
> i ran this program on DevC++ 4.9.9.2 and i'm getting some garbage
> values as output!

Your program's behavior is undefined.

Simpler:

int *p = &a.y;
int *q = &a.z;

--
Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"

The problem is not with the pointers which have been cast, it's with
the pointers which have NOT been cast.
Because &a has type "pointer to structure", adding an offset to it
does not produce a pointer inside that structure. If you want to do
this using offsetof, you should cast &a to type (unsigned char *), i.e.

Although, as others have said, it would be better in this small example
to write it simply as
int *p = &(a.y);
int *q = &(a.z);

(Note also that you don't need the "dummy" struct tag. The only reason
to name your structs this way is if you're actually going to be using
that tag, and if you're defining the structure type with a typedef, the
only reason I can think of for doing that would be if the structure
contains a pointer to its own type).

Share This Page

Welcome to The Coding Forums!

Welcome to the Coding Forums, the place to chat about anything related to programming and coding languages.

Please join our friendly community by clicking the button below - it only takes a few seconds and is totally free. You'll be able to ask questions about coding or chat with the community and help others.
Sign up now!