|
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 )
|
|
|
|
|
I included the required header file...
Thanks in advance,
Ashok.
|
|
|
|
|
Christian Graus wrote: Looks like you're missing a #include.
Seems that would have resulted in:
error C2065: 'assert' : undeclared identifier
instead. With VS6, __MODULE__ is not even part of the assert() macro so I'm not sure what to even suggest.
"Approved Workmen Are Not Ashamed" - 2 Timothy 2:15
"Judge not by the eye but by the heart." - Native American Proverb
|
|
|
|
|
Where did you get the __MODULE__ predefined macro from?
If you right click on "assert" and choose "Go to Declaration" then what file do you end up in?
It should be assert.h ( which you should be including with #include <assert.h> ).
In the RTL code with VS2003, it only uses these macros: __FILE__ and __LINE__
"If you can dodge a wrench, you can dodge a ball."
|
|
|
|
|
ya exactly,
assert(0);
and printf("\nHere %s %d \n",__FILE__,__LINE__); // for both statements I am getting the same error.
I included assert.h and tried but am unable to find the __MODULE__ predefined macro..
thanks in advance,
Ashok
|
|
|
|