structures compatibility

  • Thread starter =?ISO-8859-1?Q?Sa=EFd?=
  • Start date
?

=?ISO-8859-1?Q?Sa=EFd?=

Hi,

If I define two structures like this

struct s1 {

int a;
int b;
}

struct s2 {
int a;
int b;
int c;
}

and if I have ps2 a pointer on an s2 structure, ps1 a pointer on an s1
structure.

Can I use ps2 as a pointer on an s1 sturcture and have the a and b
correct? In ther words, does the order of the different data in a
structure follow the order in the declaration?

Thanks.
 
J

Joona I Palaste

Saïd said:
If I define two structures like this
struct s1 {
int a;
int b;
}
struct s2 {
int a;
int b;
int c;
}
and if I have ps2 a pointer on an s2 structure, ps1 a pointer on an s1
structure.
Can I use ps2 as a pointer on an s1 sturcture and have the a and b
correct? In ther words, does the order of the different data in a
structure follow the order in the declaration?

The order does, but the offsets don't have to. IOW, you are guaranteed
that the fields in struct s1 begin in the order a, b and the fields in
struct s2 begin in the order a, b, c. You are furthermore guaranteed
that the field a in struct s1 begins at the same offset as the field a
in struct s2.
You aren't guaranteed anything else. Most importantly, you aren't
guaranteed that the field b in struct s1 begins at the same offset as
the field b in struct s2. There might be a difference of thousands of
bytes, given a particularly nasty implementation.
Therefore the answer to whether you can use pointers to struct s2 as
pointers to struct s1 is "it depends on your implementation".
If struct s1 only consisted of the field a, the answer would be "yes,
knock yourself out". But as it has more fields the answer is not so
simple.
 
?

=?ISO-8859-1?Q?Sa=EFd?=

Joona said:
The order does, but the offsets don't have to. IOW, you are guaranteed
that the fields in struct s1 begin in the order a, b and the fields in
struct s2 begin in the order a, b, c. You are furthermore guaranteed
that the field a in struct s1 begins at the same offset as the field a
in struct s2.
You aren't guaranteed anything else. Most importantly, you aren't
guaranteed that the field b in struct s1 begins at the same offset as
the field b in struct s2. There might be a difference of thousands of
bytes, given a particularly nasty implementation.

And what about a specific implementastion as gcc for linux?
 
J

Joona I Palaste

Saïd said:
And what about a specific implementastion as gcc for linux?

They are off-topic for comp.lang.c. For gcc, there's gnu.gcc.help to ask
in.
 
E

Eric Sosman

Joona said:
The order does, but the offsets don't have to. IOW, you are guaranteed
that the fields in struct s1 begin in the order a, b and the fields in
struct s2 begin in the order a, b, c. You are furthermore guaranteed
that the field a in struct s1 begins at the same offset as the field a
in struct s2.
You aren't guaranteed anything else. Most importantly, you aren't
guaranteed that the field b in struct s1 begins at the same offset as
the field b in struct s2. There might be a difference of thousands of
bytes, given a particularly nasty implementation.
Therefore the answer to whether you can use pointers to struct s2 as
pointers to struct s1 is "it depends on your implementation".
If struct s1 only consisted of the field a, the answer would be "yes,
knock yourself out". But as it has more fields the answer is not so
simple.

Joona is right (I think), but as a practical matter you'll
find that offsetof(struct s1, b) == offsetof(struct s2, b).

The guarantee of equal offsets *does* hold if there's a
union with the two structs as elements:

union u { struct s1 s1; struct s2 s2; };

... because there's a special rule in the Standard to cover
this case. Now, the practical difficulty: How can a compiler
determine that no such union exists? Even if no such union
exists in the current translation unit, there might be such
a union declared in another translation unit somewhere else,
perhaps in source code that hasn't even been written yet but
will be written and compiled tomorrow and then linked with
this one. So a compiler would need to be almost supernaturally
clever to determine whetherr it was safe to let the offsets
disagree -- and the people who write compilers have more
important things to spend their time on than deviousness and
perversity (it doesn't always seem that way, but ...)

Summary: Technically and legalistically, you have no
guarantee about the offsets. In practice, though, you do.
 
X

xarax

I think a more reliable way to achieve the OP's
intent is to imbed the first struct within the
second struct.

struct s1 {
int a;
int b;
};

struct s2 {
struct s1 s1;
int c;
};

Then passing a s2 pointer as a s1 pointer should
yield the desired behavior.


--
----------------------------------------------
Jeffrey D. Smith
Farsight Systems Corporation
24 BURLINGTON DRIVE
LONGMONT, CO 80501-6906
303-774-9381
http://www.farsight-systems.com
z/Debug debugs your Systems/C programs running on IBM z/OS!


Joona said:
The order does, but the offsets don't have to. IOW, you are guaranteed
that the fields in struct s1 begin in the order a, b and the fields in
struct s2 begin in the order a, b, c. You are furthermore guaranteed
that the field a in struct s1 begins at the same offset as the field a
in struct s2.
You aren't guaranteed anything else. Most importantly, you aren't
guaranteed that the field b in struct s1 begins at the same offset as
the field b in struct s2. There might be a difference of thousands of
bytes, given a particularly nasty implementation.
Therefore the answer to whether you can use pointers to struct s2 as
pointers to struct s1 is "it depends on your implementation".
If struct s1 only consisted of the field a, the answer would be "yes,
knock yourself out". But as it has more fields the answer is not so
simple.

Joona is right (I think), but as a practical matter you'll
find that offsetof(struct s1, b) == offsetof(struct s2, b).

The guarantee of equal offsets *does* hold if there's a
union with the two structs as elements:

union u { struct s1 s1; struct s2 s2; };

.... because there's a special rule in the Standard to cover
this case. Now, the practical difficulty: How can a compiler
determine that no such union exists? Even if no such union
exists in the current translation unit, there might be such
a union declared in another translation unit somewhere else,
perhaps in source code that hasn't even been written yet but
will be written and compiled tomorrow and then linked with
this one. So a compiler would need to be almost supernaturally
clever to determine whetherr it was safe to let the offsets
disagree -- and the people who write compilers have more
important things to spend their time on than deviousness and
perversity (it doesn't always seem that way, but ...)

Summary: Technically and legalistically, you have no
guarantee about the offsets. In practice, though, you do.
 
B

Bill Cunningham

Okay why does the OP's structs not have a semi-colon after the ending brace
and the struct posting of xarax does have semi-colons?

Bill
 
J

Joona I Palaste

Bill Cunningham said:
Okay why does the OP's structs not have a semi-colon after the ending brace
and the struct posting of xarax does have semi-colons?

They should both have ending semicolons. The OP made a typo.
 
?

=?ISO-8859-1?Q?Sa=EFd?=

Joona said:
They should both have ending semicolons. The OP made a typo.

OP means me? Yes I was just presenting the structures, not actually
coding them. :)

I'll add a union to make sure the two structures have the same beginig
even if i don't use this union in my programs.

Thanks to every body.
 

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,743
Messages
2,569,478
Members
44,898
Latest member
BlairH7607

Latest Threads

Top