[comp.lang.c] why do structs have different sizes across machines?

mouse@thunder.mcrcim.mcgill.edu (der Mouse) (03/26/91)

In article <77336@bu.edu.bu.edu>, jdubb@bucsf.bu.edu (jay dubb) writes:
> Can anyone explain to me why the following short program give the
> size of the structure as 38 on a Sun 3, and 40 on an Encore Multimax:

This is a C question, not a UNIX question.  I'm crossposting to
comp.lang.c and pointing followups there.

> main()
> {
>   struct tt
>     {
>       enum {P, PP} a;
>       char b[30];
>       int c;
>     };
>   printf("%d\n",sizeof(struct tt));
> }

> I notice that making the size of b[] 32, makes the structure be 40
> bytes large on both machines.  I imagine thiis is due to the way the
> machines align fields in structures.

Bingo.

> I am worried since I am trying to send structures across sockets
> between en encore and a sun machine.

You have only two choices.  One is to assume that the machines on the
ends of the connection are, say, a Sun-3 or an Encore, and carefully
write your code so it works in all those cases.  This is not a good
idea unless you absolutely must get all the speed possible out of it,
because the other alternative is much more portable and maintainable.

The other choice is to put the structure in some portable form for
transmission over the connection.  This could mean anything from
judicious use of ntohl() and related routines to converting everything
to text.  This slows you down, of course, but in the vast majority of
the cases the gain in portability and maintainability is worth it.

> So, can someone enlighten me about the following things:

> 1) why exactly are the sizes different?

In this case, because the Sun-3 is willing to align the int on a 16-bit
boundary while the Encore inserts two bytes of padding to move it to a
32-bit boundary.  (I feel sure this is true, though I have no access to
an Encore to check.  If I have it wrong and you *have* checked, feel
free to correct me.)

> 2) what reprecussions does this have on sending the structures across
>    sockets between machines which pack them differently and trying to
>    interpret the fields on each end?

It is only the tip of the iceberg.  Basically, you don't want to send
structures in raw binary unless you really really don't care about
portability (for example, the application should be one you're willing
to write in assembly for - as a rough rule of thumb).

> 3) and most importantly, how can I avoid this problem?

You can't, portably.  You have to convert to some sort of interchange
format.

>    are there some rules (for example, I know that all structures have
>    to be a multiple of 4 bytes large,

They don't really; a VAX would be perfectly happy with a 7-byte
structure.  (I don't recall offhand whether there exists a VAX C
compiler that doesn't pad structures.)  A Sun-3 is quite happy provided
only that everything is a multiple of 16 bits.

>    and I know about compensating for byte order differences, etc.) to
>    be followed in making up structures that will ensure that they are
>    the same on any machine?

No.  There are just too many weird machines out there.

					der Mouse

			old: mcgill-vision!mouse
			new: mouse@larry.mcrcim.mcgill.edu

wollman@emily.uvm.edu (Garrett Wollman) (03/30/91)

In article <1991Mar26.065356.577@thunder.mcrcim.mcgill.edu> mouse@thunder.mcrcim.mcgill.edu (der Mouse) writes:
>In article <77336@bu.edu.bu.edu>, jdubb@bucsf.bu.edu (jay dubb) writes:
>> Can anyone explain to me why the following short program give the
>> size of the structure as 38 on a Sun 3, and 40 on an Encore Multimax:
>
>The other choice is to put the structure in some portable form for
>transmission over the connection.  This could mean anything from
>judicious use of ntohl() and related routines to converting everything
>to text.  This slows you down, of course, but in the vast majority of
>the cases the gain in portability and maintainability is worth it.

If one is really intent on sending binary structures across sockets
(presumes 4BSD IPC, so "portability" is already somewhat compromised),
there is a simple solution to the problem.  Both the Multimax (this
machine, at any rate) and the Sun-X (for appropriate values of X>=3)
support Sun's XDR, which basically allows you to feed your structure
definition to a compiler, which will create routines to portably
convert the structure into something suitable for sending across a
network, and then convert it back at the other end.  [In this day and
age, it's a fair assumption that Most Networked Unix Systems Which Are
Derived From 4BSD Support NFS, and NFS presupposes XDR.]

-GAWollman

PS:  For that matter, our SVR3 SGI machines support NFS, too...


Garrett A. Wollman - wollman@emily.uvm.edu

Disclaimer:  I'm not even sure this represents *my* opinion, never
mind UVM's, EMBA's, EMBA-CF's, or indeed anyone else's.

brnstnd@kramden.acf.nyu.edu (Dan Bernstein) (04/01/91)

In article <1991Mar30.021653.6492@uvm.edu> wollman@emily.uvm.edu (Garrett Wollman) writes:
> [In this day and
> age, it's a fair assumption that Most Networked Unix Systems Which Are
> Derived From 4BSD Support NFS, and NFS presupposes XDR.]

Yes. It is worth noting, however, that Many Networked Unix Systems Which
Are Derived From 4BSD Still Do Not Support NFS or XDR. In general it's
easier to putchar(n/256); putchar(n & 255); than to worry about an XDR
library, at least if you're trying to write portable code.

---Dan

scs@adam.mit.edu (Steve Summit) (04/01/91)

In article <29358:Mar3120:21:2991@kramden.acf.nyu.edu> brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes:
> In general it's
> easier to putchar(n/256); putchar(n & 255); than to worry about an XDR
> library, at least if you're trying to write portable code.

Or, for a truly outlandish solution, consider printf("%d\n", n); .

                                            Steve Summit
                                            scs@adam.mit.edu

ts@cup.portal.com (Tim W Smith) (04/07/91)

And don't forget about byte ordering differences between machines
when trying to exchange binary data across networks (or tapes or
disks or serial lines or whatever).

						Tim Smith