Why declare in reversed order for _WIN64?

Started by
10 comments, last by HaywireGuy 18 years, 11 months ago
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
Advertisement
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.

//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]
moe.ron
Different endianess?
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.
E8 17 00 42 CE DC D2 DC E4 EA C4 40 CA DA C2 D8 CC 40 CA D0 E8 40E0 CA CA 96 5B B0 16 50 D7 D4 02 B2 02 86 E2 CD 21 58 48 79 F2 C3
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
};

Quote:Original post by Jan Wassenberg
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.
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.
"In order to understand recursion, you must first understand recursion."
My website dedicated to sorting algorithms
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"?
E8 17 00 42 CE DC D2 DC E4 EA C4 40 CA DA C2 D8 CC 40 CA D0 E8 40E0 CA CA 96 5B B0 16 50 D7 D4 02 B2 02 86 E2 CD 21 58 48 79 F2 C3
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.
};

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.
E8 17 00 42 CE DC D2 DC E4 EA C4 40 CA DA C2 D8 CC 40 CA D0 E8 40E0 CA CA 96 5B B0 16 50 D7 D4 02 B2 02 86 E2 CD 21 58 48 79 F2 C3
Thanks Jan and everyone else, it's much clearer now. But I am still a bit
concerned about Microsoft doing that to their "globally" used header files. If
anyone of us is doing a direct offset into a structure, that code is going to
fail (though I know we should never do that).

This topic is closed to new replies.

Advertisement