May 21, 2024, 12:15:28 PM

News:

IonicWind Snippit Manager 2.xx Released!  Install it on a memory stick and take it with you!  With or without IWBasic!


Structures

Started by Zen, December 05, 2005, 08:33:22 AM

Previous topic - Next topic

0 Members and 3 Guests are viewing this topic.

Zen

What is the optional second peramater for when using the struct statement. I have seen it on here somewhere but cant seem to find it now.

Lewis

Ionic Wind Support Team

That is the structure packing value.

In C they have a pragma

#pragma pack(1)
struct somestruct {
}
#pragma pack(8)

In Aurora you just specify the packing value as the second parameter

struct somestruct, 1 {
}

Ionic Wind Support Team

Zen

Hmm i feel stupid now but what does the packing value do? ???

Lewis

Ionic Wind Support Team

Struct member elements are aligned on specific memory boundries according to ANSI specs. This is known as 'packing' and speeds up operations on Intel processors since accessing odd memory addresses generates an internal memory violation requiring the processor to use many more clock cycles to read the data.

Packing is defaulted to 8 bytes which you can change when defining the struct. For example when writing to a disk file you should specify one byte packing


struct p, 1
{
   WORD o,p;
   CHAR q;
   WORD w;
   CHAR e,r,t,y,u,i;
   WORD a;
}


the alignment of a particular variable in memory is defined as the minimum of either the packing size or the largest base member type the struct uses. NULL pad bytes are added to align the next member element to this boundry.

For example say a struct contains an INT and a CHAR

struct testUDT
{
INT a;
CHAR b;
}

Using the afore mentioned rules the size of this struct is 8 and not 5 like you would expect. Three padding bytes are added after the CHAR to make sure the struct itself is aligned on a DWORD memory boundry.

reversing the elements as in:

struct testUDT
{
char b;
INT a;
}

Alignes the INT member to the next DWORD boundry ( INT = 4 bytes and its the largest member of the UDT) so there are 3 pad bytes between 'b' and 'a' and no padding at the end of the struct;

All of this is handled in the background by the compiler.  Microsoft uses 2 byte packing for most bitmap structures in memory and 1 byte packing for anything saved/written to a disk file.

Paul.
Ionic Wind Support Team

Zen

Thanks for the explanation Paul. Not sure it all makes sense now but i will look into it some more on the net.

Thanks
Lewis

redea30591

Quote from: Lewis on December 05, 2005, 10:56:31 AM
Thanks for the explanation Paul. Not sure it all makes sense now but i will look into it some more on the net.

Thanks
Lewis

Just thought I'd add a little that might make a tad bit of since....

Consider 2 things here...

In the stone ages, we had the 8088 and the 8086.  The 8088 was an 8-bit CPU, the 8086 was a 16-bit CPU with an 8-bit bus.  Memory reads and writes where faster on the 8086 and 80286 if they where on an even word boundary.  Eg. If you read from B800:0000h it'd take less time than reading from B800:0001h.  For this reason, programmers would design their structures so they
had even byte boundaries...  But then the 32-bit CPU's came out, and they required an even Double-Word Boundary to read/write faster.... 

Also, consider compression routines, sometimes it's simplier to pad the structure with a few extra bytes and then compress the entire structure based upon a number of bits that is evenly divisable by whatever the maximum number of bits in each byte being used is... Eg. Consider a structure of console colors:

struct colors {
      int foreground;
      int background;
     int  menufore;
    int  menuback;
};


With packing of 1, the structure is 16 bytes long, but in reality we're only using 32 bits, which could be compressed to 1 int variable...

Cases like this where all the values are going to be less than 8 bits of storage can be compressed easily, and it somewhat helps to
be able to assume the entire structure is packed to a specific boundary size that's a multiple of the number of bits being used,
eg. 4 byte packing here should work nicely...., though if Aurora supports it like C supports it, you could just as easily do:

struct colors {
    int foreground:4;
    int background:4;
    int menurefore:4;
    int menuback:4;
};


etc. Where only 4 bits of data are allocated to each variable and yet they're treated as an int with a maximum value of 15....