|
mo_nica881 wrote: in some program i always see "#pragma pack(1)" included in Header. what is the role of #pragma pack(1).
It's useful to disable structure member alignment. Value of 1 disables any alignment...
For eg:
struct aligntest
{
char aChar;
int nNum;
};
Normally sizeof( aligntest ) will return 8 but the actual size is 5. Extra 3 bytes is used for padding. This is done for efficiency sake.
This could be a problem if you are using functions like memcpy to copy native type values into structures for splitting them up and you want each part to be named...
For eg:
#pragma pack( push, 1 ) // Set alignment to 1
struct IntParts
{
BYTE byPart1;
BYTE byPart2;
BYTE byPart3;
BYTE byPart4;
};
#pragma pack( pop ) // Restore previous settings
int nSplit = 123213;
IntPart ip = { 0 };
memcpy( &ip, &nSplit, sizeof( ip ));
The above operation will be dangerous with padding since sizeof of int is 4 and the sizeof the structure should also be 4, hence you have to disable padding using #pragma pack( push, 1 ) and when you are done with the setting write another #pragma pack( pop ) which resets the setting.
You should not use 1 alignment always except for above reasons.
|
|
|
|
|
|
sk8er_boy287 wrote: I'm pretty much sure (from experience) that sizeof always returns the size of the type of structure (5 for your code sample). sizeof doesn't care about memory alignment.
Wrong. Test and see.
|
|
|
|
|
sk8er_boy287 wrote: ...(5 for your code sample).
Only if #pragma pack(1) is present. By default, it will have a size of 8.
"Approved Workmen Are Not Ashamed" - 2 Timothy 2:15
"Judge not by the eye but by the heart." - Native American Proverb
|
|
|
|
|
I've just tested and you're right. I've always trusted sizeof to give me the right size of any type of structure. I find this behavior kind of weird.
However, I've also tested with arrays and the size of a single element of an array includes the padding. So there's no problem there, other than a lot of useless padding for large arrays.
I wonder what this code would do (try to copy 8 bytes into 3 ) :
#pragma pack( push, 1 ) // Set alignment to 1
struct IntParts1
{
BYTE byPart1;
BYTE byPart2;
BYTE byPart3;
};
#pragma pack( pop ) // Restore previous settings
struct IntParts2
{
BYTE byPart1;
BYTE byPart2;
BYTE byPart3;
};
IntParts1 ip1 = {0, 1, 2};
IntParts2 ip2 = {0, 1, 2};
memcpy( &ip1, &ip2, sizeof( ip1 ));
|
|
|
|
|
sk8er_boy287 wrote: I wonder what this code would do (try to copy 8 bytes into 3) :
In your example, both ip1 and ip2 are the same size (3 bytes).
"Approved Workmen Are Not Ashamed" - 2 Timothy 2:15
"Judge not by the eye but by the heart." - Native American Proverb
|
|
|
|
|
Can anyone explain that? Shouldn't the second structure be allocated using the default 8-byte alignment?
Here's another example which should copy 8 bytes into 5:
#pragma pack( push, 1 ) // Set alignment to 1
struct IntParts1
{
char byPart1;
int byPart2;
};
#pragma pack( pop ) // Restore previous settings
struct IntParts2
{
char byPart1;
int byPart2;
};
IntParts1 ip1 = {0};
IntParts2 ip2 = {0};
memcpy( &ip1, &ip2, sizeof( ip1 ) );
printf( "%d, %d\n", sizeof( IntParts1 ), sizeof( IntParts2 ) );
And don't tell me they're both 5 bytes in size because i tested this time!
|
|
|
|
|
sk8er_boy287 wrote: Here's another example which should copy 8 bytes into 5:
Actually, you're example would only copy 5 bytes.
"Approved Workmen Are Not Ashamed" - 2 Timothy 2:15
"Judge not by the eye but by the heart." - Native American Proverb
|
|
|
|
|
Something not considered here is the effect on the alignment of each member within the struct.
This makes your memcpy() from one type to another even more dangerous...
#pragma pack( push, 1 ) // Set alignment to 1
struct IntParts1
{
char byPart1;
int byPart2;
};
#pragma pack( pop ) // Restore previous settings
struct IntParts2
{
char byPart1;
int byPart2;
};
As DavidCrow mentioned, you've copied sizeof( ip1 ) (5) bytes.
This would cause you to lose 3 bytes of the source byPart2 member...not good.
Mark
"If you can dodge a wrench, you can dodge a ball."
|
|
|
|
|
I think I understand now. Thanks.
Sounds to me like it's best not to use #pragma pack at all. It hasn't bothered me until now and it doesn't seem like it has any real usage.
I don't know if MSDN says anything about this but I'm pretty sure they're aligned on byte boundaries. I could've easily created my own struct as above by mistake, and copied it's contents to an API structure. No idea what would've happened.
I suppose problems can be avoided if you don't copy your own data structures into the API ones or, if you must, copy each member separately.
|
|
|
|
|
I think of it the same way as with classes - A binary copy of one class type to another isn't
necessarily safe. That's what copy constructors and assignment operators are for.
To me, #pragma pack is only useful for cross platform/language situations. In the past I could be
assured that any language could at least deal with byte (1) packing. This especially applied
when mixing with assembly language.
For Win32, I believe the default packing of 8 is used.
For MFC it may be 4...there's so many damn nested header files it's hard to trace
Mark
"If you can dodge a wrench, you can dodge a ball."
|
|
|
|
|
I stated "For Win32, I believe the default packing of 8 is used."
I believe that's wrong Actually it varies all over the place. 4 is used in general it seems
but there are many cases of 2 and 1.
Here's a link to an article by an old MS programmer: Alignment (part 2): Packing[^]
Mark
"If you can dodge a wrench, you can dodge a ball."
|
|
|
|
|
Hi,
I'd like to make my CFrameWnd subclass not resize any smaller than a certain size. Everywhere I web-search, I see that the suggested way to do this is:
void CWndDerived::OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI)
{
// set the minimum tracking width
// and the minimum tracking height of the window
lpMMI->ptMinTrackSize.x = 200;
lpMMI->ptMinTrackSize.y = 150;
}
I type this into my (very simple) app, and set a breakpoint at the start of this function. It is never called.
Is this method still valid? (under Visual Studio 2005 c++)
Thanks,
Max
|
|
|
|
|
maxmaven wrote: CWndDerived
Are you sure this class window is window you are trying to resize ?
A quick test in simple SDI app, shows result as expected.
|
|
|
|
|
Can you tell me exactly what you did? And are you in Visual Studio 2005, C++?
I did:
SDI: doesn't work
SDI + DocView architecture: doesn't work
SDI + Split Window: doesn't work
Are you setting anything special? Or adding more than just the
OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI) function?
Thank you,
Max
|
|
|
|
|
Have you seen David's[^] reply ?
Are you sure macro ON_WM_GETMINMAXINFO is there as messsage map entry ?
|
|
|
|
|
I do not have a message map entry. How do I add one for ON_WM_GETMINMAXINFO?
Max
|
|
|
|
|
maxmaven wrote: How do I add one for ON_WM_GETMINMAXINFO?
As has already been mentioned, use ClassWizard.
"Approved Workmen Are Not Ashamed" - 2 Timothy 2:15
"Judge not by the eye but by the heart." - Native American Proverb
|
|
|
|
|
maxmaven wrote: I type this...
Did you use ClassWizard to add it? Is BEGIN_MESSAGE_MAP() correct?
"Approved Workmen Are Not Ashamed" - 2 Timothy 2:15
"Judge not by the eye but by the heart." - Native American Proverb
|
|
|
|
|
All I did was cut and paste the code into MainFrm.cpp, and add the function to the class declaration in MainFrm.h.
Max
|
|
|
|
|
Then you are missing the entry in BEGIN_MESSAGE_MAP() . It's fine to add the actual code (i.e., that which is in between the curly braces) to your functions/methods, but use ClassWizard to add the prototypes.
"Approved Workmen Are Not Ashamed" - 2 Timothy 2:15
"Judge not by the eye but by the heart." - Native American Proverb
|
|
|
|
|
How do I add the message map entry using a wizard? Do I use the "Add Member Function" wizard?
Thanks,
Max
|
|
|
|
|
Ctrl+W, unless you are using VS200x. Otherwise, see here.
"Approved Workmen Are Not Ashamed" - 2 Timothy 2:15
"Judge not by the eye but by the heart." - Native American Proverb
|
|
|
|
|
assert(0); /// for this statement I am getting the following error
error C2065: '__MODULE__' : undeclared identifier
Thanks in advance
Ashok
|
|
|
|
|
Looks like you're missing a #include.
Christian Graus - Microsoft MVP - C++
Metal Musings - Rex and my new metal blog
"I am working on a project that will convert a FORTRAN code to corresponding C++ code.I am not aware of FORTRAN syntax" ( spotted in the C++/CLI forum )
|
|
|
|