afh@PacBell.COM (Alan Hobesh) (09/06/89)
The following c code prints the size of the definded structure to be 44, when compiled on an AT&T 3B20 running UNIX V5.2.1. /*------------------------------------------------------------*/ #include <stdio.h> struct REC { char vis_date[6]; char vis_time[6]; char vis_port[2]; char vis_rec_type[2]; char vis_seq_num[5]; char vis_phone_num[10]; char vis_switch[4]; char vis_stop_dur[6]; char vis_cr; } recbuf; main() { printf("struct = %d\n",sizeof(struct REC)); } /*------------------------------------------------------------*/ However, when the code is downloaded to a PC and compiled using Turbo C, the size of the structure is reported to be 42. Why is there a difference and which is the correct size?
hartman@cbnewsc.ATT.COM (mark.a.hartman) (09/06/89)
In article <29722@pbhya.PacBell.COM> afh@PacBell.COM (Alan Hobesh) writes: > > >The following c code prints the size of the definded structure to be 44, >when compiled on an AT&T 3B20 running UNIX V5.2.1. > ... structure and code omitted ... > >However, when the code is downloaded to a PC and compiled using Turbo C, >the size of the structure is reported to be 42. > >Why is there a difference and which is the correct size? The AT&T 3B20 compiler rounds structures up to an even word length, in your case from 42 bytes to 44. If you need code that is portable between the two machines, try adding something like char fill[2]; to the end of the structure to fill it out. Then, "sizeof struct" will be the same on both machines. -- Mark Hartman hartman@ihlpm.att.com ..att!ihlpm!hartman #include <std_disclaimer.h>
gwyn@smoke.BRL.MIL (Doug Gwyn) (09/06/89)
In article <29722@pbhya.PacBell.COM> afh@PacBell.COM (Alan Hobesh) writes: >The following c code prints the size of the definded structure to be 44, >when compiled on an AT&T 3B20 running UNIX V5.2.1. [...] >However, when the code is downloaded to a PC and compiled using Turbo C, >the size of the structure is reported to be 42. >Why is there a difference and which is the correct size? Both sizes are correct. The difference is due to structure padding (probably at the end of the structure, in this particular case). C implementations differ in the amount and location of such padding. If you intended the structure to describe an externally-imposed data format, you need to be aware that there may be padding between the structure members as well as at the end, so a simple roll-in of the data into such a structure variable may not work right.
fredex@cg-atla.UUCP (Fred Smith) (09/06/89)
In article <29722@pbhya.PacBell.COM> afh@PacBell.COM (Alan Hobesh) writes: > > >The following c code prints the size of the definded structure to be 44, >when compiled on an AT&T 3B20 running UNIX V5.2.1. > stuff deleted > >However, when the code is downloaded to a PC and compiled using Turbo C, >the size of the structure is reported to be 42. > >Why is there a difference and which is the correct size? Welcome to the world of "portability"! This program reports two different values because the compilers were implemented by different people. Also, different processors have different data alignment restrictions. (I do not know what processor is used in the 3B20, so I cannot speak to it.) There is no requirement that the elements of a structure be packed tightly together in memory, i.e., with no spaces between elements. Obviously the Turbo C compiler is packing it tightly, to save space, while the Unix compiler on the 3B20 is not. Members of the 80x86 family CAN work with packed structures, but the accessing of those data structures may be less efficient than if they were not packed, depending on the particular structure's contents. Some other processors require word alignment, or alignment on a boundary equal to the size of the item stored there, or other such restrictions. Hope this helps a little Fred
henry@utzoo.uucp (Henry Spencer) (09/06/89)
In article <29722@pbhya.PacBell.COM> afh@PacBell.COM (Alan Hobesh) writes: >The following c code prints the size of the definded structure to be 44, >when compiled on an AT&T 3B20 running UNIX V5.2.1.... >However, when the code is downloaded to a PC and compiled using Turbo C, >the size of the structure is reported to be 42. > >Why is there a difference and which is the correct size? There is a difference because compilers use different rules for filling in structures. Both sizes are correct; code that assumes *any* specific size for a struct is wrong. -- V7 /bin/mail source: 554 lines.| Henry Spencer at U of Toronto Zoology 1989 X.400 specs: 2200+ pages. | uunet!attcan!utzoo!henry henry@zoo.toronto.edu
karl@haddock.ima.isc.com (Karl Heuer) (09/07/89)
>Some other processors require word alignment, or alignment on a boundary >equal to the size of the item stored there, or other such restrictions. In this particular case, the processor doesn't require any special alignment for the structure in question, but the implementation pads it anyway. (As is its right, silly though it may be.) It's not a bug, just a misfeature. Karl W. Z. Heuer (ima!haddock!karl or karl@haddock.isc.com), The Walking Lint
john@chinet.chi.il.us (John Mundt) (09/07/89)
In article <2951@cbnewsc.ATT.COM> hartman@cbnewsc.att.com (mark.a.hartman) writes: >In article <29722@pbhya.PacBell.COM> afh@PacBell.COM (Alan Hobesh) writes: >> >> >>The following c code prints the size of the definded structure to be 44, >>when compiled on an AT&T 3B20 running UNIX V5.2.1. >>However, when the code is downloaded to a PC and compiled using Turbo C, >>the size of the structure is reported to be 42. >> >>Why is there a difference and which is the correct size? > >The AT&T 3B20 compiler rounds structures up to an even word length, >in your case from 42 bytes to 44. If you need code that is portable >between the two machines, try adding something like > > char fill[2]; > >to the end of the structure to fill it out. Then, "sizeof struct" >will be the same on both machines. That is no guarantee that the two structures will be portable between both machines. Granted, both will be the same length, but the offset to different members of the structure can vary. I did not see the original structure, so if it was something like struct foo { char fee[42]; }; there would be no problem, but also no need to have a structure. However, if it were something as simple as struct foo { int x; char y[38]; }; y could be offset 2 or 4 bytes from the beginning of the structure. Further, if it were struct foo { char y[37]; int x; }; then x could conceivably be at an offset of 37, 38, 40, or 48 depending on the system, the size of the word, and where different types must be located. Moving structures from disk to different machines is not always so straight forward. Much easier to convert to ascii delimited strings and back again. -- --------------------- John Mundt Teachers' Aide, Inc. P.O. Box 1666 Highland Park, IL john@chinet.chi.il.us (312) 998-5007 (Day voice) || -432-8860 (Answer Mach) && -432-5386 Modem
scs@hstbme.mit.edu (Steve Summit) (09/07/89)
In article <2951@cbnewsc.ATT.COM> hartman@cbnewsc.att.com (mark.a.hartman) writes: >The AT&T 3B20 compiler rounds structures up to an even word length, >in your case from 42 bytes to 44. If you need code that is portable >between the two machines, try adding something like > char fill[2]; >to the end of the structure to fill it out. Then, "sizeof struct" >will be the same on both machines. If you need code that is portable between machines, don't rig it up so that you depend on things like structure sizes. One way to depend on structure size (and arrangement, and byte order, etc.) is to pass data between the machines (over the network, or on magnetic media) by writing and reading whole structures. A much better approach is to write and read an ASCII, machine- independent format. If you must pad a structure out to some known size, a common technique is to stick it in a union along with a buffer of the desired size: union tblock { /* from memory; can't find tar.c or tar.h */ struct header { char name[100]; char uid[8]; char linktype; } header; char dummy[512]; }; As long as sizeof(struct header) is less than 512, sizeof(union tblock) will be exactly 512. (This used to be the case; one of the ANSI C experts will now point out that some clause in the standard allows a compiler writer to implement things such that sizeof(struct header) could be almost anything.) Steve Summit
gwyn@smoke.BRL.MIL (Doug Gwyn) (09/07/89)
In article <14529@haddock.ima.isc.com> karl@haddock.ima.isc.com (Karl Heuer) writes: >In this particular case, the processor doesn't require any special alignment >for the structure in question, but the implementation pads it anyway. (As is >its right, silly though it may be.) It's not a bug, just a misfeature. It's not necessarily silly. When the first VAX C compiler was implemented, the implementors decided to longword-align such things even though the VAX is byte-addressable. It made typical programs run faster on the only model available at that time (VAX-11/780). That was due to the operation of the memory buffer cache.
ray@philmtl.philips.ca (Raymond Dunn) (09/08/89)
In article <10945@smoke.BRL.MIL> gwyn@brl.arpa (Doug Gwyn) writes: >In article <29722@pbhya.PacBell.COM> afh@PacBell.COM (Alan Hobesh) writes: >>Why is there a difference [of sizes of struct on different machines] > >Both sizes are correct. The difference is due to structure padding >(probably at the end of the structure, in this particular case). >C implementations differ in the amount and location of such padding. >If you intended the structure to describe an externally-imposed data >format, you need to be aware that there may be padding between the >structure members as well as at the end, so a simple roll-in of the >data into such a structure variable may not work right. In MS 'C' the compiler can be made to pack structures tightly, at the expense of the code space and execution time required to access the fields in a less efficient manner. In MSC 4.x, use the /Zp option switch. (see page 193 of the Users' Guide). In MSC 5.x, use the /Zpn option switch or #pragma pack(n), where n defines 1, 2 or 4 byte boundaries. (see page 100 of the Users' Guide). Whether or not it's proper to use such language extensions to handle externally imposed data formats is a discussion I'd rather not breach.... -- Ray Dunn. | UUCP: ..!uunet!philmtl!ray Philips Electronics Ltd. | TEL : (514) 744-8200 Ext: 2347 600 Dr Frederik Philips Blvd | FAX : (514) 744-6455 St Laurent. Quebec. H4M 2S9 | TLX : 05-824090
dune@cbnewsl.ATT.COM (Greg Pasquariello) (09/09/89)
In article <29722@pbhya.PacBell.COM> afh@PacBell.COM (Alan Hobesh) writes:
:
:
:The following c code prints the size of the definded structure to be 44,
:when compiled on an AT&T 3B20 running UNIX V5.2.1.
:However, when the code is downloaded to a PC and compiled using Turbo C,
:the size of the structure is reported to be 42.
:
:Why is there a difference and which is the correct size?
They are both correct. The structure is padded to be word aligned.
Greg Pasquariello
att!picuxa!gpasq