Author: James Robertson
Date: 16:14:30 02/14/99
Go up one level in this thread
On February 14, 1999 at 04:30:16, Bruce Moreland wrote:
>
>On February 14, 1999 at 02:40:01, James Robertson wrote:
>
>>I had problems with wierd sizes too. I was going to make my book records 12
>>bytes in size (64 bits for hash code, 32 for scores and stuff) but found that
>>even if I declared the struct:
>>
>>struct BookRecord
>>{
>> unsigned __int64 code;
>> int score;
>>}
>>
>>sizeof(BookRecord) would still = 16 bytes!!! I have no idea why, and to this day
>>my book records are 16 bytes.....
>>
>>James
>
>You are both getting killed by alignment stuff. The compiler will pad
>structures in such a manner that you won't have mis-aligned data if you make an
>array of the things.
>
>A 9-byte structure with an 32-bit value in it will pad to 12 bytes. Example:
>
> struct {
> int i, j;
> char ch;
> } v[2];
>
>It would be really bad if this thing were really made 9 bytes in size. If you
>tried to access v[1].i, you'd access a 32-bit value at offset 9 from the start
>of the array, which isn't aligned on a 32-bit boundary.
>
>On a pentium, you'll go very slow. On an Alpha (21164), the compiler would
>actually have to generate special code to handle this case, which would go
>really slow.
>
>So in order to protect you, the compiler pads your structure.
>
>I don't understand the 64-bit alignment in the example in the quoted post, but
>apparently the compiler is doing the same thing here. It is trying to align the
>structure so that you won't access the 64-bit thing on a 32-bit boundary, if you
>have an array of them.
>
>If you really want to make an unaligned structure, do:
>
> #pragma pack(1)
>
>before the structure definition, and:
>
> #pragma pack()
>
>after it. This will prevent the compiler from adding pad bytes.
>
>You should only do this if you have a structure that really really needs to be
>small (probably because you have a huge array of them), or is written to disk.
>In this case it is also a bad idea to use "int", which can change size. It's
>probably best to typedef something, I use "typedef int I32;" for Intel, for
>instance. Normally you don't care what sizeof(int) is, but when you write one
>to disk, obviously you do.
>
>Realize as well that by packing, you will pay a performance penalty.
>
>Another issue involves the order that members are declared in a structure. This
>is a bad idea:
>
> struct {
> char ch1;
> int i;
> char ch2;
> } v;
>
>Sizeof this thing should be six, you'd think, but it will actually be 12. The
>char is given one byte, but in order to avoid a misaligned access of the int, 3
>pad bytes are added. Then the int comes, which is 4 bytes, then the char, which
>is another one, then three more pad bytes. If you put the chars together:
>
> struct {
> char ch1;
> char ch2;
> int i;
> } v;
>
>you'd get two pad bytes after ch2, and none at the end of the structure, so
>you'd save four bytes per element. You could put the int first, which would
>cause the pad bytes to be at the end of the structure, if this is more to your
>liking.
>
>If you really wanted to save space here, this is on the of the few times that
>you'd want to use "short", since this would make this structure half the size (4
>bytes), at the cost of some performance, which you might not care about if you
>rarely actually access the elements in the array.
>
>bruce
Thanks. This really clears a lot of stuff up, not only dealing with this case. I
really appreciate this post.
James
This page took 0 seconds to execute
Last modified: Thu, 15 Apr 21 08:11:13 -0700
Current Computer Chess Club Forums at Talkchess. This site by Sean Mintz.