Computer Chess Club Archives


Search

Terms

Messages

Subject: Re: size of C++ class question...

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.