sizeof(struct) and padding
Richard A. O'Keefe
ok at goanna.cs.rmit.oz.au
Mon Oct 22 11:07:49 AEST 1990
In article <1229 at sun13.scri.fsu.edu>, mayne at sun10.scri.fsu.edu (William (Bill) Mayne) writes:
> "Big deal!" you say? Actually it could make an important differnce
> if the structure is being written as a record to a file. Then extra
> file space will be used. Unless I intend to read or write arrays of
> records some of the time, changing the number of records handled,
> with each operation, this is a real waste.
> The $64K question is: How do I portably get the actual size of
> a structure without padding when I need that rather than
> what sizeof() tells me?
There is no such thing as "the actual size of a structure without padding".
Much of the padding required for alignment is likely to be within the
record. Consider
struct foo { char a; double d; short s; void *p; };
^ ^
I've marked the two places that padding is likely to go on a machine that
requires 32-bit alignment for doubles and data pointers. They are *inside*.
Suppose we could squeeze the padding out. The size of the record with
padding is 20 bytes. Without padding it'd be 15. Big deal. If you
order the fields in a struct thus:
first long double
then double
then float
then pointer-to-function
then pointer
then long
then int
then short
last char
then all the padding required for alignment is likely to be at the end,
and on a 32-bit byte-addressed machine the total amount of padding is
likely to be at most 3 bytes. This isn't going to be perfect on all
machines, but it's pretty good for most. (It's a generalisation of the
ordering prudent Fortran programmers use within COMMON blocks.)
If you are only writing one or two records of a particular type to a
file, why do you care about the padding? If you are writing thousands,
then you may well want to read and write arrays of them.
If it is absolutely essential that you write your records in the most
compact form, then don't use ``raw'' fwrite and fread. Write your own
int fwrite_foo(FILE *f, struct foo *p) { ... }
int fread_foo(FILE *f, struct foo *p) { ... }
functions that write/read the fields separately.
But above all, keep in mind that in C, there is no such thing as "the
actual size of a structure without padding". "sizeof" is as actual
as it ever gets.
--
Fear most of all to be in error. -- Kierkegaard, quoting Socrates.
More information about the Comp.lang.c
mailing list