N
Not Really Me
We have run into some code that is using a hand calculated offset to
dereference a pointer to a struct element to create a pointer to the start
of the struct.
(Example code below), basically a function is passed a pointer to a struct
member that is not the first member in the struct. The function actually
needs a pointer to the struct itself. To get that pointer, the code is
subtracting the hand calculated offset of the member, from the from the
pointer to the member, to create a pointer to the start of the struct. Ugly?
The problem we see is that c99 6.3.2.3p5 says that subtracting an int from a
pointer that is not pointing to an array is implementation dependent. In
theory this should be portable code.
To overcome this, someone suggested using the C99 offsetof macro to do get
the offset. Otherwise the math remains the same.
Is using offsetof still a violation of 6.3.2.3p5?
Is so, is there any safe way to do this (short of rewriting the code to pass
a pointer to the start of the struct)?
struct { int apples, int oranges, int lemons, int grapes, int limes } Fruit;
struct Fruit *pfruit;
foo( pfruit->grapes);
void foo( int *purple_fruit )
{
struct Fruit *local_fruit;
int apple;
local_fruit = &purple_fruit->grapes - offsetof( Fruit, grapes);
apple = local_fruit->apples;
}
Scott
dereference a pointer to a struct element to create a pointer to the start
of the struct.
(Example code below), basically a function is passed a pointer to a struct
member that is not the first member in the struct. The function actually
needs a pointer to the struct itself. To get that pointer, the code is
subtracting the hand calculated offset of the member, from the from the
pointer to the member, to create a pointer to the start of the struct. Ugly?
The problem we see is that c99 6.3.2.3p5 says that subtracting an int from a
pointer that is not pointing to an array is implementation dependent. In
theory this should be portable code.
To overcome this, someone suggested using the C99 offsetof macro to do get
the offset. Otherwise the math remains the same.
Is using offsetof still a violation of 6.3.2.3p5?
Is so, is there any safe way to do this (short of rewriting the code to pass
a pointer to the start of the struct)?
struct { int apples, int oranges, int lemons, int grapes, int limes } Fruit;
struct Fruit *pfruit;
foo( pfruit->grapes);
void foo( int *purple_fruit )
{
struct Fruit *local_fruit;
int apple;
local_fruit = &purple_fruit->grapes - offsetof( Fruit, grapes);
apple = local_fruit->apples;
}
Scott