struct padding and sizeof 
Author Message
 struct padding and sizeof

Hello,

I have a struct similar to this

struct s{
int first_member;
int a_member;
int last_menber;

Quote:
};

struct s a;

I am sending this struct from one program to another via a TCP stream. The 2
programs could be on different platforms.

Is there a standard or at least generally accepted way to guarantee the
layout of the struct without getting into compiler and os implementations?
(I think the answer is explicitly no but I thought I would ask before
assuming.)

More directly to my problem:
This struct is being padded with an extra int on one platform, the padding
is at the end of the struct so the only thing it affects is the size of the
structure. I am using sizeof to determine how many bytes to transmit and
sizeof is returning 16 not 12. Is there a clever way to get the size of the
struct without the padding without doing something ugly like:
(int)((char*)&a.last_member - (char*)&a.first_member) +
sizeof(a.last_member)

Thanks,
chris



Tue, 12 Aug 2003 06:24:56 GMT  
 struct padding and sizeof

Quote:
> Hello,
> I have a struct similar to this
> struct s{
> int first_member;
> int a_member;
> int last_menber;
> };
> struct s a;
> I am sending this struct from one program to another via a TCP stream. The 2
> programs could be on different platforms.
> Is there a standard or at least generally accepted way to guarantee the
> layout of the struct without getting into compiler and os implementations?
> (I think the answer is explicitly no but I thought I would ask before
> assuming.)

The only guarantee you'll have is that the struct members will be in the
same order. First, sizeof(int) might well be different on different
platforms, second, the compiler is free to insert padding bytes anywhere
it likes.
Given that all your members are of the same type, one solution would be
to "flatten out" the struct by sending each member separately. TCP won't
know or care the bytes are supposed to form ints, so it'll happily
forward them without padding. This means, though, that on the receiving
end you'll have to work out yourself which bytes belong to which ints.

Quote:
> More directly to my problem:
> This struct is being padded with an extra int on one platform, the padding
> is at the end of the struct so the only thing it affects is the size of the
> structure. I am using sizeof to determine how many bytes to transmit and
> sizeof is returning 16 not 12. Is there a clever way to get the size of the
> struct without the padding without doing something ugly like:
> (int)((char*)&a.last_member - (char*)&a.first_member) +
> sizeof(a.last_member)

Well, one way to get the size of the structure disregarding any padding
bytes would be to add the sizeofs of the members together. Beyond that
and your solution, ANSI C offers no help.

--

| Kingpriest of "The Flying Lemon Tree" G++ FR FW+ M- #108 D+ ADA N+++|
| http://www.helsinki.fi/~palaste       W++ B OP+                     |
\----------------------------------------- Finland rules! ------------/

"I am looking for myself. Have you seen me somewhere?"
   - Anon



Tue, 12 Aug 2003 06:59:22 GMT  
 struct padding and sizeof

Quote:

> Hello,

> I have a struct similar to this

> struct s{
> int first_member;
> int a_member;
> int last_menber;
> };
> struct s a;

> I am sending this struct from one program to another via a TCP stream. The 2
> programs could be on different platforms.

> Is there a standard or at least generally accepted way to guarantee the
> layout of the struct without getting into compiler and os implementations?
> (I think the answer is explicitly no but I thought I would ask before
> assuming.)

<OT>
There is a standard but it is better discussed in comp.unix.programmer

You can use the Posix functions:

#include <netinet/in.h>

ntohl   (Network to host long 4 bytes)
htonl   (Host to network long 4 bytes)
ntohs   (Network to host long 2 bytes)
htons   (Host to network long 2 bytes)

All data members should be converted to network byte order before
sending and then
converted to host byte order after they have been received.
</OT>

Quote:

> More directly to my problem:
> This struct is being padded with an extra int on one platform, the padding
> is at the end of the struct so the only thing it affects is the size of the
> structure. I am using sizeof to determine how many bytes to transmit and
> sizeof is returning 16 not 12. Is there a clever way to get the size of the
> struct without the padding without doing something ugly like:
> (int)((char*)&a.last_member - (char*)&a.first_member) +
> sizeof(a.last_member)

Is it possible to add your own padding into the structure. From personal
experience I have found that it is best to put all 4 byte members first,
followed by 2 byte members, then followed by 1 byte members (including
char arrays). This should cause the structures to be the same on a lot
of platforms without additional padding added by yourself.

Adrian Cornish
AP



Tue, 12 Aug 2003 07:15:42 GMT  
 struct padding and sizeof

Quote:

>Hello,

>I have a struct similar to this

>struct s{
>int first_member;
>int a_member;
>int last_menber;
>};
>struct s a;

>I am sending this struct from one program to another via a TCP stream. The 2
>programs could be on different platforms.

>Is there a standard or at least generally accepted way to guarantee the
>layout of the struct without getting into compiler and os implementations?
>(I think the answer is explicitly no but I thought I would ask before
>assuming.)

There's no way (or at least no way that I know of) to do this without
breaking the struct down into its components, but if you're communicating
between two different platforms you'll probably need to do that anyways
to deal with possible differences in endianness or size.

If you can convert the struct into a string of ASCII (or EBCDIC,
or another character set of your choice) characters (for example,
"{17,42,59}") at one end, send those as a string of bytes, and convert
it back into a struct at the other end, that will guarantee that the
end result in the receiving program is the same as the initial struct in
the sending program; if you're only sending ints, this might be overkill
(or it might not).

If you don't want to convert to and from text, the hton[ls] and
ntoh[ls] functions (which convert to and from a standard byte order)
may be useful for handling endianness differences; they're not ISO C,
but most networking libraries should have them (or equivalent functions).

dave

--

My wife is not speaking to me because I spent a large chunk of today reading it
instead of carving turkey, entertaining dull relatives etc.... . next time, can
you guys write a slightly less good book ?!!?  --Mark McIntyre on _C Unleashed_



Tue, 12 Aug 2003 08:04:39 GMT  
 struct padding and sizeof



Quote:

> > Hello,

> > I have a struct similar to this

> > struct s{
> > int first_member;
> > int a_member;
> > int last_menber;
> > };
> > struct s a;

> > I am sending this struct from one program to another via a TCP stream.
The 2
> > programs could be on different platforms.

> > Is there a standard or at least generally accepted way to guarantee the
> > layout of the struct without getting into compiler and os
implementations?
> > (I think the answer is explicitly no but I thought I would ask before
> > assuming.)

> The only guarantee you'll have is that the struct members will be in the
> same order. First, sizeof(int) might well be different on different
> platforms, second, the compiler is free to insert padding bytes anywhere
> it likes.

ObNit: the compiler is not free to insert padding bytes before the first
member.

Also, there's also the possibility that the two different platforms have
different representations for ints -- for example, one might be
little-endian, and the other big-endian.

- Show quoted text -

Quote:
> Given that all your members are of the same type, one solution would be
> to "flatten out" the struct by sending each member separately. TCP won't
> know or care the bytes are supposed to form ints, so it'll happily
> forward them without padding. This means, though, that on the receiving
> end you'll have to work out yourself which bytes belong to which ints.

> > More directly to my problem:
> > This struct is being padded with an extra int on one platform, the
padding
> > is at the end of the struct so the only thing it affects is the size of
the
> > structure. I am using sizeof to determine how many bytes to transmit and
> > sizeof is returning 16 not 12. Is there a clever way to get the size of
the
> > struct without the padding without doing something ugly like:
> > (int)((char*)&a.last_member - (char*)&a.first_member) +
> > sizeof(a.last_member)

> Well, one way to get the size of the structure disregarding any padding
> bytes would be to add the sizeofs of the members together. Beyond that
> and your solution, ANSI C offers no help.

> --

> | Kingpriest of "The Flying Lemon Tree" G++ FR FW+ M- #108 D+ ADA N+++|
> | http://www.helsinki.fi/~palaste       W++ B OP+                     |
> \----------------------------------------- Finland rules! ------------/

> "I am looking for myself. Have you seen me somewhere?"
>    - Anon



Tue, 12 Aug 2003 13:49:53 GMT  
 struct padding and sizeof

Quote:

> Hello,

> I have a struct similar to this

> struct s{
> int first_member;
> int a_member;
> int last_menber;
> };
> struct s a;

> I am sending this struct from one program to another via a TCP stream. The 2
> programs could be on different platforms.

In communication you don't send struct, but a stream of bytes, which are more
likely to be called octets.

Quote:
> Is there a standard or at least generally accepted way to guarantee the
> layout of the struct without getting into compiler and os implementations?

No. Struct is language and plattform and compiler dependent!

Quote:
> (I think the answer is explicitly no but I thought I would ask before
> assuming.)

> More directly to my problem:
> This struct is being padded with an extra int on one platform, the padding
> is at the end of the struct so the only thing it affects is the size of the
> structure. I am using sizeof to determine how many bytes to transmit and
> sizeof is returning 16 not 12. Is there a clever way to get the size of the
> struct without the padding without doing something ugly like:
> (int)((char*)&a.last_member - (char*)&a.first_member) +
> sizeof(a.last_member)

No No!

You need a protocol, in a simple client-server model, you need to define the
layout the of request and response messages. Do not define these messages in
terms of structs, but in a language independent way.

SIZE MEMBER
2       first
2       second

Then you need to choose encoding, the simplest is perhaps ASCII, which will fix
endian problems. To make conversion routines between binary and ASCII, a simple
way is to look at sprintf(), strto??() functions.

More advanced schemes will use e.g. TLV formatting and binary encoding.

--
Tor <torust AT online DOT no>



Tue, 12 Aug 2003 22:25:32 GMT  
 struct padding and sizeof

Quote:

> Is there a standard or at least generally accepted way to guarantee the
> layout of the struct without getting into compiler and os implementations?

No.

You will need to be familiar with the platform you are sending the data
to and verify that you are interpreting the data correctly on the
receiving platform.

You may even run into Endian issues.

--
== Eric Gorr ===== http://www.*-*-*.com/ :9293199 ===
"Therefore the considerations of the intelligent always include both
benefit and harm." - Sun Tzu
== Insults, like {*filter*}, are the last refuge of the incompetent... ===



Mon, 18 Aug 2003 02:37:12 GMT  
 
 [ 7 post ] 

 Relevant Pages 

1. sizeof(struct) and padding

2. C++ 5.0 and sizeof (struct) / padding ?

3. sizeof (struct) ! = sizeof struct elements

4. SizeOf Misreporting Struct w/ Bitfield, Union, and Nested Struct

5. padding in a statically initialized struct

6. Padding in structs

7. padding a struct to a defined size

8. padding in structs..

9. padding in structs

10. Q: howto prevent struct padding

11. create a padded struct?

12. preventing struct padding

 

 
Powered by phpBB® Forum Software