Why declare in reversed order for _WIN64?
Good day people, I am seeing this in WinSock.h. But I'm not sure why do we have to "reverse" the declaration order if we're compiling it for _WIN64?
struct servent
{
#ifdef _WIN64
char FAR * s_proto;
short s_port;
#else
short s_port;
char FAR * s_proto;
#endif
};
Thanks in advance for any replies
Structure alignment is usually done from highest size to lowest size in a descending order. This is done to attempt to keep structures aligned to whatever boundary the system desires ( 32bit 64bit, etc) and to reduce the amount of padding that would be added to a structure. Ptrs in Win64 are now going to be 8bytes, while the short will remain 2 bytes.
[EDIT]
hmmm. Thats odd, now that I re-read your post, either way the char * would be bigger than the short.. There goes that theory =) Unless that is meant for backward compatibility for 16-bit systems too...
[EDIT]
//Win32 structstruct fine{ int m_int; (4bytes no padding) long m_long; (4bytes no padding) int m_int2; (4bytes no padding)};// but in win64struct bad{ int m_int; (4bytes, 4bytes of padding (8 total bytes) ) long m_long; (8bytes, 0 padding) int m_int; (4bytes, 4bytes of padding (8 total bytes) )};struct win64Good{ long m_long; (8bytes no padding) int m_int; (m_int and m_int2 fill up 8 consecutive bytes..no padding) int m_int2;};
[EDIT]
hmmm. Thats odd, now that I re-read your post, either way the char * would be bigger than the short.. There goes that theory =) Unless that is meant for backward compatibility for 16-bit systems too...
[EDIT]
moeron is correct as to the desire to change. Now it breaks binary compatibility, but Win64 in native mode does anyway, which is why they can get away with it.
Don't see any difference byte order would make.
Don't see any difference byte order would make.
Thanks guys,
This is the complete structure (I shouldn't have removed the first two
members). But even in this case padding of 6 bytes will still happen to "short
s_port" too, right? Unless it's better to have padding at the end of the
structure rather than somewhere in the middle.
struct servent
{
char FAR * s_name;
char FAR * FAR * s_aliases;
#ifdef _WIN64
char FAR * s_proto;
short s_port;
#else
short s_port;
char FAR * s_proto;
#endif
};
This is the complete structure (I shouldn't have removed the first two
members). But even in this case padding of 6 bytes will still happen to "short
s_port" too, right? Unless it's better to have padding at the end of the
structure rather than somewhere in the middle.
struct servent
{
char FAR * s_name;
char FAR * FAR * s_aliases;
#ifdef _WIN64
char FAR * s_proto;
short s_port;
#else
short s_port;
char FAR * s_proto;
#endif
};
Quote:Original post by Jan WassenbergYes, excellent answer. It's one of those things where someone didn't do it the best way to begin with. I get those a lot.
moeron is correct as to the desire to change. Now it breaks binary compatibility, but Win64 in native mode does anyway, which is why they can get away with it.
Don't see any difference byte order would make.
Quote:But even in this case padding of 6 bytes will still happen to "short
s_port" too, right?
Negative - padding is only strictly required before a data member. Sufficiently studly compilers could avoid adding padding to the end of a struct by checking alignment requirements of subsequent data.
iMalc:
Quote:Yes, excellent answer. It's one of those things where someone didn't do it the best way to begin with. I get those a lot.
:) Hindsight is 20/20; once released, it's reasonable to set APIs in stone.
How do you mean "I get those a lot"?
Thanks Jan, if I get your point correctly, the "bad" structure Moeron shown may
or may not have padding at the final "int" then? If no padding at the end were
to happen, the whole structure will be of size 8 + 8 + 4 = 20 bytes. That doesn't look
like an "optimized" size to me... Just wondering.
struct bad
{
int m_int1;
long m_long;
int m_int2; // No padding.
};
or may not have padding at the final "int" then? If no padding at the end were
to happen, the whole structure will be of size 8 + 8 + 4 = 20 bytes. That doesn't look
like an "optimized" size to me... Just wondering.
struct bad
{
int m_int1;
long m_long;
int m_int2; // No padding.
};
Exactly.
As to "optimized", it's a bit wasteful, yes. But the compiler cannot do anything about it; struct members must not be rearranged, since the coder may access them via pointer+direct offset.
This is why we must manually order from largest-smallest.
As to "optimized", it's a bit wasteful, yes. But the compiler cannot do anything about it; struct members must not be rearranged, since the coder may access them via pointer+direct offset.
This is why we must manually order from largest-smallest.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement