#pragma pack(1)
struct BITMAPFILEHEADER //header of a BMP-file
{
short bfType; //Ident of a BMP-file ''BM''
long bfSize; //size of our file
short bfRes1; //something
short bfRes2; //something else
long bfOffBits; //the offset to the image bits
};
#pragma pack()
#pragma pack() stuff
I know it has been mentioned on an other forum already but I didn''t find a good answer on the question.
Does anyone have a good explanation of the #pragma pack(n) directive? VC++ 6.0 only tells it can accept 1,2,4,8,16 as n. But I obviously don''t know what they mean.
I''m using it as follows in my bmp structures and I know it is related to the byteorder: (as can be derived from the hex view of both, an original bmp and a program-made bmp)
Could anyone explain what the values passed to pack() mean?
===========================
UNKNOWN caused an invalid page fault in module unknown at 0000:bff80eb6
: win98 with multiple sclerose
Variable alignment. The pack directive is for letting the compiler know how big a ''word'' it should be aligning the varibles on in your structure. Larger values mean extra space at the end of the struct, or possibililty space in between variables in the struct.
Packing the variables right improves performance, at the expense of portability. pack(1) is equivalent to aligning on byte boundries, which means no extra space at all. Structs that you expect to read and write from files (particuarly across multiple platforms) should be packed on byte boundaries.
Packing the variables right improves performance, at the expense of portability. pack(1) is equivalent to aligning on byte boundries, which means no extra space at all. Structs that you expect to read and write from files (particuarly across multiple platforms) should be packed on byte boundaries.
Thanks, I think I know what you''re talking about, there is still one question.
Why on earth, when I look at the hex view of the bitmap, c++ adds two zero bytes after the bfType. The bfType is a short and should be two bytes long in the file. Why does the compiler add two clean bytes. I''ve never had this problem when reading or writing files to/from structures, and now suddenly it occurs.
Of course it disappears when I use the #pragma pack(1) directive, but still: why does it occur when I don''t specify that any bytes should be added?
Why on earth, when I look at the hex view of the bitmap, c++ adds two zero bytes after the bfType. The bfType is a short and should be two bytes long in the file. Why does the compiler add two clean bytes. I''ve never had this problem when reading or writing files to/from structures, and now suddenly it occurs.
Of course it disappears when I use the #pragma pack(1) directive, but still: why does it occur when I don''t specify that any bytes should be added?
The compiler adds it so that it aligns on a certain boundary, x86 are 32-bit cpu''s and take a performance hit if they are accessing memory that is not aligned to 32-bit''s (I believe it''s 32-bit''s not sure though).
So essentially the compiler does this to optimize your program .
So essentially the compiler does this to optimize your program .
quote:Original post by SwSh
Thanks, I think I know what you''re talking about, there is still one question.
Why on earth, when I look at the hex view of the bitmap, c++ adds two zero bytes after the bfType. The bfType is a short and should be two bytes long in the file. Why does the compiler add two clean bytes. I''ve never had this problem when reading or writing files to/from structures, and now suddenly it occurs.
Of course it disappears when I use the #pragma pack(1) directive, but still: why does it occur when I don''t specify that any bytes should be added?
The intel is a 32 bit processor, so by default it aligns variables every four bytes.
In this case you''ve got a two byte variable followed by a four byte variable. Access will be fastest if the end of the second variable comes four bytes after the end of the first variable so... the compiler inserts two extra bytes.\
The long and the short of it is that the default packing on an intel CPU is ''4.''
To elaborate on AP''s post, consider what would happen if it didn''t try to align on a 4-byte boundary. This is based on a 32-bit processor that always retrieves data in 32-bit sections. ie: x86.
If you set it to byte alignment (pack 1), then everything after bfType would cross a 4-byte boundary. Any time that the CPU tried to access anything after bfType it would have to perform two separate retrievals from memory, and perhaps swap them. Thus, slower than 4-byte alignment.
It''d be even worse if that bfType was a char or a single byte.
Then when the cpu tried to retrieve bfSize, it would have to perform the same two retrievals (one from 0000, one from 0004), then do a few swaps to get everything into the proper order.
If you set it to byte alignment (pack 1), then everything after bfType would cross a 4-byte boundary. Any time that the CPU tried to access anything after bfType it would have to perform two separate retrievals from memory, and perhaps swap them. Thus, slower than 4-byte alignment.
It''d be even worse if that bfType was a char or a single byte.
[0000] bfType[0001] bfSize[0002] ...[0003] ...[0004] ...[0005] bfRes1
Then when the cpu tried to retrieve bfSize, it would have to perform the same two retrievals (one from 0000, one from 0004), then do a few swaps to get everything into the proper order.
Just to cap off the discussion nicely, if you want your structures to work as well as is possibly with 1 byte packing, sort your variables. You''ll find that declaring the largest variables first will give you the best packing you''re gonna get without dummy space.
Thanks a lot!
Now I think I''ve got it. So the byte alignment has actually not much to do with the sizeof(type). It''s just a matter of experimenting and nice sorting in structures to not waste proc cycles and code.
I''ll have to experiment some on that though.
tnx.
===========================
UNKNOWN caused an invalid page fault in module unknown at 0000:bff80eb6
: win98 with multiple sclerose
Now I think I''ve got it. So the byte alignment has actually not much to do with the sizeof(type). It''s just a matter of experimenting and nice sorting in structures to not waste proc cycles and code.
I''ll have to experiment some on that though.
tnx.
===========================
UNKNOWN caused an invalid page fault in module unknown at 0000:bff80eb6
: win98 with multiple sclerose
the only reason i found to use a byte alignment was when loading file-headers into a header-object. if you don''t set the alignment to 1 for a header-class/struct, you''ll get wrong values while reading (because the fread writes into the ''empty'' memory. you''ll have to do put #pragma pack(1) / #pragma pack() around these classes/structs, or read each variable one by one
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement